Android 在横向模式或翻转方向后无法从传感器获取方向
我想用安卓系统来确定摄像机的方向。我的代码在纵向上运行得很好(我通过慢慢地转一圈,间隔1秒看更新来测试),但在横向上根本不起作用——数字似乎是随机变化的。在从肖像画切换到风景画之后,它也变得完全不正常。这是我的密码Android 在横向模式或翻转方向后无法从传感器获取方向,android,orientation,accelerometer,sensors,Android,Orientation,Accelerometer,Sensors,我想用安卓系统来确定摄像机的方向。我的代码在纵向上运行得很好(我通过慢慢地转一圈,间隔1秒看更新来测试),但在横向上根本不起作用——数字似乎是随机变化的。在从肖像画切换到风景画之后,它也变得完全不正常。这是我的密码 public void onSensorChanged(SensorEvent event) { switch (event.sensor.getType()) { case Sensor.TYPE_ACCELEROMETER: accelerome
public void onSensorChanged(SensorEvent event) {
switch (event.sensor.getType()) {
case Sensor.TYPE_ACCELEROMETER:
accelerometerValues = event.values.clone();
break;
case Sensor.TYPE_MAGNETIC_FIELD:
geomagneticMatrix = event.values.clone();
break;
default:
break;
}
if (geomagneticMatrix != null && accelerometerValues != null) {
float[] R = new float[16];
float[] I = new float[16];
float[] outR = new float[16];
//Get the rotation matrix, then remap it from camera surface to world coordinates
SensorManager.getRotationMatrix(R, I, accelerometerValues, geomagneticMatrix);
SensorManager.remapCoordinateSystem(R, SensorManager.AXIS_X, SensorManager.AXIS_Z, outR);
float values[] = new float[4];
SensorManager.getOrientation(outR,values);
float direction = normalizeDegrees((float) Math.toDegrees(values[0]));
float pitch = normalizeDegrees((float) Math.toDegrees(values[1]));
float roll = normalizeDegrees((float) Math.toDegrees(values[2]));
if((int)direction != (int)lastDirection){
lastDirection = direction;
for(CompassListener listener: listeners){
listener.onDirectionChanged(lastDirection, pitch, roll);
}
}
}
}
知道我做错了什么吗?我坦率地承认我不是100%理解这一点。我也不知道为什么谷歌不喜欢定向传感器——这似乎是一个共同的愿望。 < P>你有没有想过,当你从肖像变成风景时,加速度轴会改变?就像Y轴变成Z轴一样。这可能是奇怪行为的一个来源。我似乎已经解决了它,或者至少改进到了我知道问题所在的程度。我加入了一个过滤器,这样我就可以记住上一次的读数,并对其应用一个增量,而不是发送一个传感器读数。每个新传感器点最多可增加5度。这将完全过滤掉奇怪的跳跃,并迫使其收敛到一个值。我偶尔会看到奇怪的跳跃,但我想我需要的是一个更复杂的过滤器。新代码:
public void onSensorChanged(SensorEvent event) {
if (event.accuracy == SensorManager.SENSOR_STATUS_UNRELIABLE)
return;
switch (event.sensor.getType()) {
case Sensor.TYPE_ACCELEROMETER:
accelerometerValues = event.values.clone();
break;
case Sensor.TYPE_MAGNETIC_FIELD:
geomagneticMatrix = event.values.clone();
break;
}
if (geomagneticMatrix != null && accelerometerValues != null) {
float[] R = new float[16];
float[] I = new float[16];
float[] outR = new float[16];
//Get the rotation matrix, then remap it from camera surface to world coordinates
SensorManager.getRotationMatrix(R, I, accelerometerValues, geomagneticMatrix);
SensorManager.remapCoordinateSystem(R, SensorManager.AXIS_X, SensorManager.AXIS_Z, outR);
float values[] = new float[4];
SensorManager.getOrientation(outR,values);
int direction = filterChange(normalizeDegrees(Math.toDegrees(values[0])));
int pitch = normalizeDegrees(Math.toDegrees(values[1]));
int roll = normalizeDegrees(Math.toDegrees(values[2]));
if((int)direction != (int)lastDirection){
lastDirection = (int)direction;
lastPitch = (int)pitch;
lastRoll = (int)roll;
for(CompassListener listener: listeners){
listener.onDirectionChanged(lastDirection, pitch, roll);
}
}
}
}
//Normalize a degree from 0 to 360 instead of -180 to 180
private int normalizeDegrees(double rads){
return (int)((rads+360)%360);
}
//We want to ignore large bumps in individual readings. So we're going to cap the number of degrees we can change per report
private int filterChange(int newDir){
int change = newDir - lastDirection;
int circularChange = newDir-(lastDirection+360);
int smallestChange;
if(Math.abs(change) < Math.abs(circularChange)){
smallestChange = change;
}
else{
smallestChange = circularChange;
}
smallestChange = Math.max(Math.min(change,5),-5);
return lastDirection+smallestChange;
}
传感器更改时的公共无效(传感器事件){
if(event.accurity==SensorManager.SENSOR\u状态\u不可靠)
返回;
开关(event.sensor.getType()){
外壳传感器.U型加速计:
accelerometerValues=event.values.clone();
打破
外壳传感器。类型\u磁场:
地磁矩阵=event.values.clone();
打破
}
if(地磁矩阵!=null和加速度计值!=null){
浮动[]R=新浮动[16];
浮动[]I=新浮动[16];
浮动[]输出=新浮动[16];
//获取旋转矩阵,然后将其从摄影机曲面重新映射到世界坐标
SensorManager.getRotationMatrix(R、I、加速度计值、地磁矩阵);
SensorManager.remapCoordinationSystem(R,SensorManager.AXIS_X,SensorManager.AXIS_Z,outR);
浮动值[]=新浮动[4];
SensorManager.getOrientation(输出、值);
int direction=filterChange(normalizedgrees(数学toDegrees(值[0]));
int pitch=标准化程度(数学到度(值[1]);
int roll=normalizedgrees(数学toDegrees(值[2]);
如果((int)方向!=(int)最后方向){
lastDirection=(int)方向;
lastPitch=(int)音高;
lastRoll=(int)roll;
for(CompassListener:侦听器){
方向改变(最后方向、音高、滚动);
}
}
}
}
//将0到360度的角度规格化,而不是-180到180度
专用整数规格化灰度(双拉德){
返回值(整数)((rads+360)%360);
}
//我们希望忽略单个读数中的大起伏。因此,我们将限制每个报告可以更改的度数
私有int filterChange(int newDir){
int change=newDir-lastDirection;
int circularChange=newDir-(lastDirection+360);
最微小的变化;
if(数学abs(变化)