【发布时间】:2014-11-09 18:32:57
【问题描述】:
我正在使用 Sensortag CC2541(已连接到 Nexus 手机)
我正在使用这个传感器的磁力计来制作一个简单的指南针。我正在使用以下等式来查找北、南、西和东。
Direction (y>0) = 90 - [arcTAN(x/y)]*180/pi
Direction (y<0) = 270 - [arcTAN(x/y)]*180/pi
Direction (y=0, x<0) = 180.0
Direction (y=0, x>0) = 0.0
这是我在 updateMagnetometer 方法中使用的代码
@Override
public void onUpdateMagnetometer(SensorTagManager mgr, Point3D b) {
super.onUpdateMagnetometer(mgr, b);
double m=0;
if(b.x < 0.0 && (b.y < 0.01 && b.y > 0.0))
m = 180;
else if(b.x > 0.0 && (b.y < 0.01 && b.y > 0.0))
m = 0;
else if(b.y > 0.0)
m = 90 - (Math.atan(b.x/b.y))*(180/Math.PI);
else if(b.y < 0.0)
m = 270 - (Math.atan(b.x/b.y))*(180/Math.PI);
final float rot = (float) m;
runOnUiThread(new Runnable() {
@Override
public void run() {
pointer.setRotation(-rot); //pointer is the image of my compass
}
});
}
但是当我运行它时,无论我移动、旋转多少或改变传感器的位置,指南针总是卡在北方和西方之间。
我可能会犯什么错误?
而且,我在互联网上查看了很多关于指南针帮助的信息。但我什么也找不到。任何编码技巧、伪代码或使用磁力计、加速度计和/或陀螺仪制作指南针的提示???
额外信息
所以这是我的主要课程。这些方法每x 秒调用一次以更新读数。
PS:我的传感器有 2 个按钮(左右)
mStManager.enableSensor(Sensor.MAGNETOMETER,MAGNETOMETER_UPDATE_PERIOD);
mStManager.enableSensor(Sensor.ACCELEROMETER,MAGNETOMETER_UPDATE_PERIOD);
@Override
public void onUpdateAmbientTemperature(SensorTagManager mgr, double temp) {
super.onUpdateAmbientTemperature(mgr, temp);
}
@Override
public void onUpdateAccelerometer(SensorTagManager mgr, Point3D acc) {
super.onUpdateAccelerometer(mgr, acc);
}
@Override
public void onUpdateBarometer(SensorTagManager mgr, double pressure, double height) {
super.onUpdateBarometer(mgr, pressure, height);
}
@Override
public void onUpdateGyroscope(SensorTagManager mgr, Point3D ang) {
super.onUpdateGyroscope(mgr, ang);
}
@Override
public void onUpdateHumidity(SensorTagManager mgr, double rh) {
super.onUpdateHumidity(mgr, rh);
}
@Override
public void onUpdateInfraredTemperature(SensorTagManager mgr, double temp) {
super.onUpdateInfraredTemperature(mgr, temp);
}
@Override
public void onUpdateKeys(SensorTagManager mgr, boolean left, boolean right) {
super.onUpdateKeys(mgr, left, right);
if (right) {
mgr.calibrateMagnetometer();
}
}
@Override
public void onUpdateMagnetometer(SensorTagManager mgr, Point3D b) {
super.onUpdateMagnetometer(mgr, b);
}
}
所以基本上在onUpdateMagnetometer 方法中,b 包含我的阅读。它属于Point3D 类,如下所示
public class Point3D {
public double x, y, z;
public Point3D(double x, double y, double z) {
this.x = x;
this.y = y;
this.z = z;
}
public double norm() {
return Math.sqrt(x*x + y*y + z*z);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
long temp;
temp = Double.doubleToLongBits(x);
result = prime * result + (int) (temp ^ (temp >>> 32));
temp = Double.doubleToLongBits(y);
result = prime * result + (int) (temp ^ (temp >>> 32));
temp = Double.doubleToLongBits(z);
result = prime * result + (int) (temp ^ (temp >>> 32));
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Point3D other = (Point3D) obj;
if (Double.doubleToLongBits(x) != Double.doubleToLongBits(other.x))
return false;
if (Double.doubleToLongBits(y) != Double.doubleToLongBits(other.y))
return false;
if (Double.doubleToLongBits(z) != Double.doubleToLongBits(other.z))
return false;
return true;
}
public String toString() {
return "[" + this.x + ", " + this.y + ", " + this.z + "]";
}
}
【问题讨论】:
-
我很乐意帮助你,但我真的不明白你的代码想要做什么。首先,
Direction (y=0, x>0) = 0.0不是一个等式,我什至不知道这意味着什么。其次,使用单字母变量是让人们忽略您的问题的好方法,因为它们很难阅读。b是什么?它是否包含某种来自磁力计的读数? -
我从一个网站得到
Direction (y=0, x>0) = 0.0。这基本上意味着如果磁力计的y等于0并且它的x大于0,那么指南针的指针必须在0.0(北)。其余的与他的相似。此外,b是磁力计的读数。在参数中,b 是Point3D类的一个,其中x, y, z是磁力计的变量。对象b还包含诸如norm()、toString()...等方法...但唯一且最重要的字段是x,y,z。 -
对,我可以看到
b是一个 Point3D,它在你的代码中。我的问题是:里面有什么数据?x,y,z是否描述了单位圆上的一个点、某种四元数、每个轴上的磁场强度等?你没有给我们足够的代码来知道b的值来自哪里。 -
我想我找到了你从...获得这些“方程式”的网站aerospace.honeywell.com/~/media/Images/… 他们只有两个象限中的arctan,这真是太奇怪了。好像那样不对。
-
好的,然后在下面看到我的答案。
标签: java android sensors compass magnetometer