向电子罗盘进发[未完]

【声明】 电子罗盘对我们这种东西南北都分不清楚的小白来说,真是吸引力无穷啊~ 特别是现在手机导航仪里面都有这么个东西,心痒难耐,也想自己来弄下。 但是网络上光有公式,没有推导。于是很闲的我们,就把羞答答的她,推倒了。。 以下部分公式来自网络,部分来自推导;图片大部分来自网络,少部分自己绘制。





【材料】:

arduino 板一块

HMC5883 - 三轴方位传感器

MPU6050 - 六轴加速度传感器

面包板,线材若干





(一) 什么是磁偏角和方位公式


磁偏角

2013-7-27 07:19 上传
(16.05 KB)

磁偏角





磁偏角,即现实中指北针指向的磁极(地磁极)和我们地图上标注的传统意义的磁极是不重合的,有一个夹角。 你看地球仪上的地球也不是歪脖子转动么,就是这个意思。



下面是几何时间,如何定义方位。这里采用了反正切角的表达方式。


Atan2, 反正切角

2013-7-27 07:21 上传
(24.96 KB)

Atan2, 反正切角




公式

2013-7-27 07:21 上传
(21.17 KB)

公式





为了做这个电子罗盘,反正切角(Atan2)这种不知哪个星球来的东西都学习了。

π是180度,2π是360度,1/2π是90度... 其实这个反正切角就是射线(x,y)和x轴正向间的夹角。没什么好神秘的。如果y<0,射线在x轴下方,那么角度从x轴正向顺时针旋转,而且是负值;如果y>0,角度从x轴正向逆时针旋转。大量图示和公式来自基维百科。



几个特殊点的取值。

(0,0)夹角为0

(0, 1)对于的复平面夹角为π/2,

(−1, 0)对于复平面的夹角为π,

(0, −1)对于复平面的夹角为3π/2,



下面看下atan2和我们一般atan的区别。三维图,找到x,y轴就省事了。其实只是个计量方法的不同,不晓得为什么要弄得这么复杂的样子。


atan2, 按照y>0 和 y < 0分别从逆时针和顺时针计算

2013-7-27 07:21 上传
(33.74 KB)

atan2, 按照y>0 和 y < 0分别从逆时针和顺时针计算




tan,就是我们一般的正切

2013-7-27 07:21 上传
(30.18 KB)

tan,就是我们一般的正切





****<br />
看完了这些基础知识,我们来分析honeywell的HMC5883三轴数位罗盘对角度的计算公式。



angle= atan2(y,x) * (180 / 3.14159265) + 180;



其实就是这样的:

角度 = atan2(y,x) * (180 / π) + 180,这里角度用0~360°表示



因为atan2(y,x) 算出来的会是多少π,所以后面用了个 180/π来换算成度数(0~360°)。但是,但是后面那个 +180是干嘛?



如果是60°的角,+180就变成了240°,从A点变成了B点变成了下面这个图。


+180°引起的效果

2013-7-27 07:21 上传
(8.65 KB)

+180°引起的效果





仔细想想公式,因为这种反正切角的范围是从-π到π (-180°~180°), 而我们通常读出的指南针角度是0°~360°,所以需要把这个范围进行平移180°,到指南针的角度。但是这样一来,原来60°的角度变成了240°,也就是,整个象限沿着虚线被"镜像"了一下。





下图x轴要变成"南“的位置,好吧,这样就正常了。


p8880518.jpg

2013-7-27 07:21 上传
(6.01 KB)





于是我们得到了下面这个方位判断:



if((angle < 22.5) || (angle > 337.5 ))

Serial.print("South");

if((angle > 22.5) && (angle < 67.5 ))

Serial.print("South-West");

if((angle > 67.5) && (angle < 112.5 ))

Serial.print("West");

if((angle > 112.5) && (angle < 157.5 ))

Serial.print("North-West");

if((angle > 157.5) && (angle < 202.5 ))

Serial.print("North");

if((angle > 202.5) && (angle < 247.5 ))

Serial.print("NorthEast");

if((angle > 247.5) && (angle < 292.5 ))

Serial.print("East");

if((angle > 292.5) && (angle < 337.5 ))

Serial.print("SouthEast");



假设我们是60°角,也就是指北针正北顺时针转60度位置,应该在NE(东北)位置,套用上面的公式,60 + 180 = 240°,然后套用上面的条件判断:angle > 202.5° 并且angle < 247.5°,处于NorthEast (东北)位置,正确。
via - 极客工坊

标签: Arduino教程