我一直试图让我的头围绕Android方向传感器一段时间.我以为我明白了.然后我意识到我没有.现在我想(希望)我对它有更好的感觉,但我仍然不是100%.我将尝试解释我对它的不完整理解,并希望如果我在部分错误或填写任何空白,人们将能够纠正我.
我想我的经度是0度(本初子午线)和纬度0度(赤道).这个位置实际上位于非洲海岸附近的海域,但请耐心等待.我把手机放在我面前,这样手机的底部指向我的脚; 我面向北方(朝向格林威治),因此电话的右侧指向东方向非洲.在这个方向(参考下图)我的X轴指向东方,Z轴指向南方,Y轴指向天空.

现在,手机上的传感器可以让您在这种情况下计算设备的方向(而不是位置).这部分总是让我感到困惑,可能是因为我想在我接受它确实有效之前理解它是如何工作的.看起来这款手机采用了两种不同技术的组合来确定其方向.
在我做到这一点之前,想象一下,回到原来在上面提到的方向上经纬度为0度的那片想象中的土地上.想象一下,你被蒙住眼睛,你的鞋子固定在游乐场环形交叉路口.如果有人在后面推你,你会向前(向北)前进,然后伸出双手来打破你的摔倒.同样地,如果有人将你的左肩推开,你的右手就会摔倒.你的内耳有"引力传感器" (youtube clip),它可以让你检测你是向前/向后,向左/向下或向下(向上!!).因此,人类可以检测与手机相同的X和Z轴周围的对齐和旋转.
现在想象有人现在在环形交叉口旋转90度,这样你现在面向东方.您正在围绕Y轴旋转.这个轴是不同的,因为我们无法在生物学上检测它.我们知道我们有一定的角度,但我们不知道与行星的磁北极有关的方向.相反,我们需要使用外部工具......磁罗盘.这使我们能够确定我们面临的方向.我们的手机也是如此.
现在这款手机还配备了3轴加速度计.我不知道它们是如何工作的,但我想象它的方式是将重力想象为从天空中落下的恒定和均匀的"雨"并想象上图中的轴作为可以检测流过的雨量的管.当手机直立时,所有下雨都会流过Y'管.如果手机逐渐旋转使其屏幕朝向天空,流过Y的雨量将减少到零,而通过Z的量将稳定增加,直到最大雨量流过.同样,如果我们现在将手机放在侧面,X管将最终收集最大量的雨水.因此,根据手机的方向,通过测量流过3管的雨量,您可以计算方向.
这款手机还有一个电子罗盘,其行为类似于普通罗盘 - 它的"虚拟针"指向磁北.的Android合并来自这两个传感器的信息,以使得每当一个SensorEvent的TYPE_ORIENTATION产生values[3]阵列具有
值[0]:方位角- (磁北的罗盘方位东)
的值[1]:节距,绕x轴旋转(是电话向前或向后倾斜)
值[2]:滚动,围绕y轴旋转(手机在其左侧或右侧倾斜)
所以我认为(即我不知道)Android给出方位角(罗盘方位)的原因而不是第三个加速度计的读数是指南针轴承更有用.我不确定为什么他们不赞成这种类型的传感器,因为现在看来你需要在系统中为SensorEvents类型注册一个监听器TYPE_MAGNETIC_FIELD.value[]需要将事件的数组转换为SensorManger.getRotationMatrix(..)方法以获得旋转矩阵(见下文),然后将其传递给SensorManager.getOrientation(..)方法.有谁知道为什么Android团队弃用了Sensor.TYPE_ORIENTATION?这是一种效率的东西吗?这是对类似问题的评论中隐含的内容,但您仍需要在development/samples/Compass/src/com/example/android/compass/CompassActivity.java示例中注册不同类型的侦听器.

我现在想谈谈旋转矩阵.(这是我最不确定的地方)所以上面我们有Android文档中的三个数字,我们称之为A,B和C.
A = SensorManger.getRotationMatrix(..)方法图并表示World的坐标系
C = SensorManager.getOrientation(..)方法图
所以我的理解是A代表"世界的坐标系",我认为它指的是地球上的位置作为(纬度,经度)夫妇与可选的(海拔)给出的方式.X是"东向"坐标,Y是"北向"坐标.Z指向天空并代表高度.
电话协调系统如图B所示是固定的.它的Y轴总是指向顶部.旋转矩阵由电话不断计算,并允许两者之间的映射.所以我认为旋转矩阵将B的坐标系转换为C是正确的吗?因此,当您调用SensorManager.getOrientation(..)方法时,您使用values[]具有与图C对应的值的数组.当手机指向天空时,旋转矩阵是单位矩阵(矩阵数学等价于1),这意味着当设备对齐时不需要映射与世界的坐标系统.
好.我想我现在最好停下来.就像我之前说的那样,我希望人们能告诉我在哪里搞砸了或帮助了人们(或者让人们更加困惑!)
android orientation bearing device-orientation compass-geolocation
我想在谷歌地图视图上的我的位置显示一个箭头,显示我相对于目的地位置(而不是北方)的方向.
a)我使用磁力计和加速度计的传感器值计算了北方.我知道这是正确的,因为它与谷歌地图视图中使用的指南针对齐.
b)我使用myLocation.bearingTo(destLocation)计算了从我的位置到目的地位置的初始方位;
我错过了最后一步; 从这两个值(a和b)我用什么公式来得出手机相对于目的地位置的方向?
感谢任何有关心灵的帮助!
我一直在试验iPhone 4上的指南针和陀螺仪,并希望得到一些我正在解决的问题的帮助.我想通过使用陀螺仪的数据来弥补指南针的缓慢.
使用CMMotionManager和它的CMDeviceMotionobject(motionManager.deviceMotion),我得到了CMAttitude对象.如果我错了(请),请纠正我,但这是我从CMAttitude对象的yaw属性中推断出来的(我不需要pitch也不是roll为了我的目的):
yaw范围从0到PI当手机正在指向下方(由所指示的deviceMotion.gravity.z)和逆时针方向摆动,并0以-PI顺时针方向摆动时yaw范围分别为-PIto 0和PIto0locationManager.heading.magneticHeading),我看到罗盘给出了从值0到360与值顺时针摆动时增加好吧,所以一起使用所有这些信息,我能够得到一个我称之为的值horizontal,无论设备是向上还是向下,都会给出值0,360并在设备顺时针摆动时增加(尽管我我在deviceManager.gravity.z周围时仍然遇到麻烦0- yaw价值在这个gravity.z价值上变得非常惊人).
在我看来,我可以使用映射到的计算值"同步" horizontal和magneticHeading值,并在我感觉指南针"赶上"时"同步"该值.horizontalmagneticHeadinghorizontalmagneticHeading
所以我的问题:
CMDeviceMotion是否正确使用陀螺仪数据并且上面列出的假设是正确的?yaw在 …我正在为移动设备制作一个"指南针".我有以下几点:
point 1 (current location): Latitude = 47.2246, Longitude = 8.8257
point 2 (target location): Latitude = 50.9246, Longitude = 10.2257
Run Code Online (Sandbox Code Playgroud)
另外我有以下信息(来自我的android手机):
The compass-direction in degree, wich bears to the north.
For example, when I direct my phone to north, I get 0°
Run Code Online (Sandbox Code Playgroud)
我怎样才能创建一个"指南针"箭头,向我展示指向方向的方向?
这有数学问题吗?
谢谢!
编辑:好的,我找到了一个解决方案,它看起来像这样:
/**
* Params: lat1, long1 => Latitude and Longitude of current point
* lat2, long2 => Latitude and Longitude of target point
*
* headX => x-Value of built-in phone-compass
*
* Returns …Run Code Online (Sandbox Code Playgroud) 我的android应用程序显示了世界上某个特定位置的方向,因此需要获得指南针度.
这是我用来计算学位的代码:
public void getDirection() {
mySensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
List<Sensor> mySensors = mySensorManager.getSensorList(Sensor.TYPE_ORIENTATION);
if(mySensors.size() > 0){
mySensorManager.registerListener(mySensorEventListener, mySensors.get(0), SensorManager.SENSOR_DELAY_UI);
}
else{
TextView alert = (TextView)findViewById(R.id.instruct);
alert.setText(getString(R.string.direction_not_found));
myCompassView.setVisibility(myCompassView.INVISIBLE);
}
}
private SensorEventListener mySensorEventListener = new SensorEventListener(){
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub
}
@Override
public void onSensorChanged(SensorEvent event) {
// TODO Auto-generated method stub
compassBearing = (float)event.values[0];
float bearing;
bearing = compassBearing - templeBearing;
if (bearing < 0)
bearing = 360 + bearing;
myCompassView.updateDirection(bearing); …Run Code Online (Sandbox Code Playgroud) 我发现当我启动游戏时,指南针经常出现问题.物体将飞来飞去,而不是它们应该在的地方.但是,如果我将手机移动到八字形(或者只是随机向一定方向挥动),所有东西都会在半分钟内卡入到位.
指南针未校准时,硬件是否知道?我是否有可能检测到这一点并弹出一条消息告诉用户"你的机器人指南针需要校准.请以水平的八字形动作移动手机,直到此消息消失."
本周末,我花了几分钟时间将一个算法打包在一个标题中(以度为单位)并返回一个String作为基本方向(我在我正在使用的安卓指南针应用程序中使用它).我最终得到的是:
private String headingToString(Float heading)
{
String strHeading = "?";
Hashtable<String, Float> cardinal = new Hashtable<String, Float>();
cardinal.put("North_1", new Float(0));
cardinal.put("Northeast", new Float(45));
cardinal.put("East", new Float(90));
cardinal.put("Southeast", new Float(135));
cardinal.put("South", new Float(180));
cardinal.put("Southwest", new Float(225));
cardinal.put("West", new Float(270));
cardinal.put("Northwest", new Float(315));
cardinal.put("North_2", new Float(360));
for (String key: cardinal.keySet())
{
Float value = cardinal.get(key);
if (Math.abs(heading - value) < 30)
{
strHeading = key;
if (key.contains("North_"))
{
strHeading = "North";
}
break;
}
}
return strHeading;
}
Run Code Online (Sandbox Code Playgroud)
我的问题是,这是最好的方法吗?虽然我还没有在网上搜索过例子,但它必须已经多次完成.还有其他人试过这个并找到了一个更整洁的解决方案吗?
编辑Reverand的Thilo's,shinjin和Chrstoffer的回复:
解决方案
public …Run Code Online (Sandbox Code Playgroud) 我正在创建一个应用程序,我需要根据设备的方向定位ImageView.我使用MagneticField和Accelerometer Sensors中的值来计算设备方向
SensorManager.getRotationMatrix(rotationMatrix, null, accelerometerValues, magneticFieldValues)
SensorManager.getOrientation(rotationMatrix, values);
double degrees = Math.toDegrees(values[0]);
Run Code Online (Sandbox Code Playgroud)
我的问题是ImageView的定位对方向的变化非常敏感.使imageview不断跳到屏幕上.(因为度数变化)
我读到这可能是因为我的设备接近可能影响磁场读数的东西.但这不是它看起来的唯一原因.
我尝试下载一些应用程序,发现" 3D罗盘 "和" 指南针 "的读数仍然非常稳定(当设置噪声滤波器时),我想在我的应用程序中使用相同的行为.
我读到我可以通过添加" 低通滤波器 " 来调整读数的"噪音" ,但我不知道如何实现这一点(因为我缺乏数学).
我希望有人可以帮助我在我的设备上创建更稳定的读数,其中设备的一点点移动不会影响当前的方向.现在我做了一个小
if (Math.abs(lastReadingDegrees - newReadingDegrees) > 1) { updatePosition() }
Run Code Online (Sandbox Code Playgroud)
过滤噪音的升值.但它不能很好地工作:)
algorithm android signal-processing orientation compass-geolocation
我在我的应用程序中使用MapView来显示一些注释.在iOS 7中,指南针随机出现在地图上.我无法重现错误,因为它随机出现,但我想禁用它.任何想法如何禁用它?
更新:我发现不是随机出现,而是出现在特定的手势上.当您使用2个手指并向右滑动而另一个向左滑动时.
在我的应用程序中,我有一个经度为1的固定位置.现在,使用iPhone设备的用户可以移动到任何地方,甚至他可以旋转他的设备,箭头(一些uiimageview)应该指向该修复位置,这样用户每次都会获得指向该位置的方向.我尝试如下.
-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
CLLocationCoordinate2D here = newLocation.coordinate;
[self calculateUserAngle:here];
}
-(void) calculateUserAngle:(CLLocationCoordinate2D)user {
NSLog(@"my destination is %f ; %f", fixlocLat, fixlocLon);
degrees = degrees + atan2(sin(fixlocLon-user.longitude)*cos(fixlocLat),cos(user.latitude)*sin(fixlocLat) - sin(user.latitude)*cos(fixlocLat)*cos(fixlocLon-user.longitude));
//get angle between user location and fix location
}
- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading
{
arrow.transform = CGAffineTransformMakeRotation((degrees-newHeading.trueHeading) * M_PI / 180);
}
Run Code Online (Sandbox Code Playgroud)
但上面的代码总是将箭头旋转到约.每个位置北2-3度.
我的问题类似于这个Stack Overflow问题.但是使用此链接中的代码我的方向错误.请帮帮我.
如果任何使用加速度计或gyrodata的想法对我有帮助.
提前.
iphone xcode objective-c cllocationmanager compass-geolocation