搜索
bottom↓
楼主: zksniper

【分享心得】9DOF姿态融合 四元数 欧拉角转换 有代码有内涵

  [复制链接]

出0入0汤圆

发表于 2014-4-8 10:05:04 | 显示全部楼层
zksniper 发表于 2014-4-8 09:47
接哪个I2C都没什么影响

噢,楼主我看你虽然用了MPU的DMP功能,但为什么不用直接读出来的四元数,然后计算欧拉角呢,而是用最原始的加速度数据、陀螺仪数据,然后通过IMU算法计算姿态角,这样做有什么优势吗?我现在是用DMP读出的四元数,然后直接计算的欧拉角,roll和pitch都很准,我现在只想校正下yaw就好,我是做空中三维鼠标的,电机什么的没有,所以也没有影响,现在就是yaw不准

出0入0汤圆

发表于 2014-4-8 10:24:01 | 显示全部楼层
楼主,在看你的程序,讲的已经很细了,但还是有一些地方不太明白,请问一下你的这个程序yaw准吗?因为你用的是三个传感器集成的芯片,我用的是MPU6050+HMC5883L,不知道我这样的组合能不能校正yaw,使得yaw也很准

出0入0汤圆

 楼主| 发表于 2014-4-8 10:34:56 | 显示全部楼层
hfjydq 发表于 2014-4-8 10:24
楼主,在看你的程序,讲的已经很细了,但还是有一些地方不太明白,请问一下你的这个程序yaw准吗?因为你用 ...

这里面大部分人用的是mpu9150,绝大部分人用的是MPU6050+HMC5883L,你说准不准,跟硬件没多大关系,这俩芯片尽量放一起,居中,注意轴向,代码是关键

这让我想起了很久之前,我还在考虑磁力计下面要不要铺铜。

出0入0汤圆

发表于 2014-4-8 10:39:33 | 显示全部楼层
zksniper 发表于 2013-9-10 17:24
内部的DMP得出的四元数不太好用,转化为欧拉角以后会有下面这个问题:
板子的角度稍微变化一下,DMP输出 ...

楼主,我用DMP没发现你说的上述问题,roll和pitch的灵敏度和精确度都还可以呀

出0入0汤圆

发表于 2014-4-8 10:41:39 | 显示全部楼层
zksniper 发表于 2014-4-8 10:34
这里面大部分人用的是mpu9150,绝大部分人用的是MPU6050+HMC5883L,你说准不准,跟硬件没多大关系,这俩 ...

楼主有没有关于HMC5883L校正yaw的的代码呀,分享一下呀,发现楼主有个很大的优点,就是思路非常清晰!!!

出0入0汤圆

发表于 2014-4-8 11:27:22 | 显示全部楼层
zksniper 发表于 2013-12-18 09:56
如果是代码问题,那你需要把你的代码贴出来,如果是理论问题,那你需要详细说明情况。 ...

楼主,我现在要做的不是四轴飞控,我要做的是3维空中鼠标,我想问下楼主可有什么方法得到空间3维的相对位移,你们做飞控的一般都是空间的3个角度,我现在不但要得到3个角度,还要3个相对位移(3维坐标),平时的鼠标就是2个坐标(x,y),我现在想得到3个坐标,楼主有什么好办法呀

出0入0汤圆

发表于 2014-4-8 12:57:42 | 显示全部楼层
zksniper 发表于 2014-4-8 10:34
这里面大部分人用的是mpu9150,绝大部分人用的是MPU6050+HMC5883L,你说准不准,跟硬件没多大关系,这俩 ...

花了一上午时间,终于把这篇帖子看完了,楼主讲的很细了,学了很多东西,但还是有很多不懂的地方……

出0入0汤圆

发表于 2014-4-8 14:16:47 | 显示全部楼层
本帖最后由 hfjydq 于 2014-4-8 14:21 编辑

楼主,请教下,你的系统时钟是多少M?  72M吗?

出0入0汤圆

发表于 2014-4-9 08:52:50 | 显示全部楼层
楼主,请教下,你的AHRSUpdate(MPU9150)移植到MPU6050上面需要注意哪些东西?

出0入0汤圆

发表于 2014-4-9 08:57:57 | 显示全部楼层
if(!i2cwrite(MPU9150_Addr, P_M_1, 1, data_write))
          {
                   printf("\r\n set_mpu9150_ClockSource complete ......\n\r");
          }
          else
          {
                   printf("\r\n set_mpu9150_ClockSource error ......\n\r");
                 GPIO_SetBits(GPIOB, GPIO_Pin_9);
                 while(1);
          }
还有  为什么你每次设置失败就把GPIOB9置高呢?为了检测某一步设置失败吗?

出0入0汤圆

 楼主| 发表于 2014-4-9 09:22:57 | 显示全部楼层
本帖最后由 zksniper 于 2014-4-9 09:25 编辑
hfjydq 发表于 2014-4-9 08:57
if(!i2cwrite(MPU9150_Addr, P_M_1, 1, data_write))
          {
                   printf("\r\n set_mpu9150_ClockSource com ...


看来你基础还不够

1.代码工程文件里可以查看跑多少Mhz,在system_xxxx.c下
2.AHRSupdate并不是mpu9150专用的,它对应的是加速度计、陀螺仪、磁力计的融合,而mpu6050只有加速度计和陀螺仪,你说该怎么办?
3.我那个pin对应的是我的LED,失败后进入else,然后还加了死循环,当然是为了停止代码并有个提示,指出哪个地方出错了

慢慢来吧,有些东西自己仔细找找思考一下就会有答案,问我还得等着,还不如问百度,除非有些东西百度没有,论坛里也没人提到过,并且经过你的长期思考还毫无头绪,不过我相信,
这样的问题对于你来说也应该很少了,只有一些算法的原创和改进上或许会有问题。

出0入0汤圆

发表于 2014-4-9 09:33:00 | 显示全部楼层
以前虽然学过一段时间,但确实,刚做编程工作一个多月!
1.没仔细看,但看你用的103系列的,感觉应该是72M
2.外扩一个磁力计
3.明白啦

出0入0汤圆

 楼主| 发表于 2014-4-9 12:34:35 | 显示全部楼层
hfjydq 发表于 2014-4-9 09:33
以前虽然学过一段时间,但确实,刚做编程工作一个多月!
1.没仔细看,但看你用的103系列的,感觉应该是72M
...

未必是72Mhz,也有可能是108Mhz,我用的不是ST的片子,只不过兼容ST,你看看吧,我也忘记了

出0入0汤圆

发表于 2014-4-9 13:29:40 | 显示全部楼层
zksniper 发表于 2014-4-9 12:34
未必是72Mhz,也有可能是108Mhz,我用的不是ST的片子,只不过兼容ST,你看看吧,我也忘记了 ...

查了下system_那个源文件,确实是108MHz的

出0入0汤圆

发表于 2014-4-9 14:48:40 | 显示全部楼层
还麻烦下楼主,dmp_read_fifo(gyro, accel, quat, &sensor_timestamp, &sensors,&more);这个函数,第一个读出的是陀螺仪原始数据,第二个独处的是加速度计原始数据,第三个读出的是四元数,后三个分别是什么数据呀??万分感谢啦

出0入0汤圆

发表于 2014-4-9 15:48:28 | 显示全部楼层
楼主,再打扰一下,我刚测试了下利用DMP的原始加速度数据和陀螺仪数据,发现都是0,但四元数正常输出的,这个原始数据还有什么地方单独使能吗

出0入0汤圆

 楼主| 发表于 2014-4-9 16:28:57 | 显示全部楼层
hfjydq 发表于 2014-4-9 15:48
楼主,再打扰一下,我刚测试了下利用DMP的原始加速度数据和陀螺仪数据,发现都是0,但四元数正常输出的,这 ...

DMp输出的accel和gyro不是原始数据了,而是经过校准后的数据,比自己校准的强,不过频率不高。对速度有要求就不要用了。没要求的话这个用着不错

都是0说明你代码有问题

出0入0汤圆

发表于 2014-4-9 17:05:16 | 显示全部楼层
//******读取MPU6050数据****************************************
void READ_MPU6050(void)
{
   BUF[0]=Single_Read(MPU6050_Addr,GX_L);
   BUF[1]=Single_Read(MPU6050_Addr,GX_H);
   A_X=        (BUF[1]<<8)|BUF[0];
   A_X/=16.4;   
这个我看别人的程序,他为什么A_X要除以16.4呢?

出0入0汤圆

发表于 2014-4-10 12:52:47 | 显示全部楼层
zksniper 发表于 2013-12-2 10:47
更新-采用AHRSUpdate算法进行姿态融合:
这段时间一直没有太多时间搞这玩意,不过苦恼多日的AHRSUpdate算法 ...

楼主这个代码磁力计校正了吗

出0入0汤圆

发表于 2014-4-10 14:01:20 | 显示全部楼层
木君之上 发表于 2014-2-19 19:44
我也是,用了DMP和自检后,放十几分钟也不会飘,一直在0.1左右,挺好的,就是速度慢了些,才200Hz, ...

你的yaw不飘????

出0入0汤圆

发表于 2014-4-10 14:04:20 | 显示全部楼层
好强大,先Mark一下,有时间好好研究一下算法。

出0入0汤圆

发表于 2014-4-10 14:07:53 | 显示全部楼层
mark......

出0入0汤圆

发表于 2014-4-10 14:57:17 | 显示全部楼层
//设置MPU9150的时钟源为GX的PLL
          data_write[0]=0x01;                                //GX_PLL:0x01
          if(!i2cwrite(MPU9150_Addr, P_M_1, 1, data_write))
          {
                   printf("\r\n set_mpu9150_ClockSource complete ......\n\r");
          }
          else
          {
                   printf("\r\n set_mpu9150_ClockSource error ......\n\r");
                 GPIO_SetBits(GPIOB, GPIO_Pin_9);
                 while(1);
          }


这个地址P_M_1不是设置电源管理的吗?而且一般都设置为0x00,请教大神为什么设置为0x01,还有这个到底是设置电源的还是时钟源的

出0入0汤圆

 楼主| 发表于 2014-4-10 15:24:01 | 显示全部楼层
hfjydq 发表于 2014-4-10 14:57
//设置MPU9150的时钟源为GX的PLL
          data_write[0]=0x01;                                //GX_PLL:0x01
          if(!i2cwrite(MPU9150_Addr ...

这是设置时钟源的,PLLSource

出0入0汤圆

发表于 2014-4-10 15:38:24 | 显示全部楼层
zksniper 发表于 2014-4-10 15:24
这是设置时钟源的,PLLSource

楼主大神你好,我现在开始移植你的AHRS这个程序了,你用的9150,我用的是6050,里面的地址定义的地方没有什么药修改的吧,除了磁力计部分,磁力计我打算用我的HMC5883原始数据代替你这部分,至于磁力计矫正,我也打算用你的方法,顺便问一下,楼主知道怎么求出空间相对位移吗?毕竟楼主对惯导这块很熟悉,想问下楼主有没有做过3维鼠标,或者有没有方案,拜谢
        for(i=0;i<5;i++)   //第一次读取的compsaa数据是错的,因此要多读几次保证以后数据正确,芯片bug
          {
        mpu_set_bypass(1);                     //开启bypass,必须有这句代码
        mpu_get_compass_reg(mag, &timestamp);  //读取compass数据
        //进行x y轴的校准,未对z轴进行校准,参考MEMSense的校准方法
        init_mx =((float)mag[1]) - 8;                                               
        init_my =((float)mag[0]) * 1.046632 - 1.569948;
        init_mz =(float)-mag[2];
        mpu_set_bypass(0);                                                //关闭bypass,必须有这句代码
        printf("mx=%f, my=%f, mz=%f \n\r", init_mx, init_my, init_mz);
          }

出0入0汤圆

 楼主| 发表于 2014-4-10 15:45:28 | 显示全部楼层
hfjydq 发表于 2014-4-10 15:38
楼主大神你好,我现在开始移植你的AHRS这个程序了,你用的9150,我用的是6050,里面的地址定义的地方没有 ...

这帖子的代码,你只需要参考四元数和欧拉角部分就行,其他的没什么参考价值,很多地方都需要改进

出0入0汤圆

发表于 2014-4-10 22:15:06 | 显示全部楼层
楼主,你的航向角公式是不是错了啊。atan2的分子是不是该分母换一下啊?

出0入0汤圆

 楼主| 发表于 2014-4-11 09:24:48 | 显示全部楼层
billhsu 发表于 2014-4-10 22:15
楼主,你的航向角公式是不是错了啊。atan2的分子是不是该分母换一下啊?

哪个公式?贴出来看看

出0入0汤圆

发表于 2014-4-11 09:51:33 | 显示全部楼层
zksniper 发表于 2014-4-10 15:45
这帖子的代码,你只需要参考四元数和欧拉角部分就行,其他的没什么参考价值,很多地方都需要改进 ...

那请教下楼主有没有6050的AHRS工程代码?分享下呀,地址寄存器什么的不熟悉,短时间不能搞定呀,拜谢

出0入0汤圆

发表于 2014-4-11 10:39:56 | 显示全部楼层
请教楼主,MPU6050和MPU9150,除了在磁力计方面的寄存器是多加的,其它部分的寄存器,MPU9150兼容MPU6050吗

出0入0汤圆

发表于 2014-4-11 10:50:03 | 显示全部楼层
zksniper 发表于 2014-4-11 09:24
哪个公式?贴出来看看

就是通过磁来计算航向角的那个公式。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2014-4-11 10:50:54 | 显示全部楼层
绝对的好东西!学习了

出0入0汤圆

发表于 2014-4-11 11:23:14 | 显示全部楼层
zksniper 发表于 2014-4-10 15:24
这是设置时钟源的,PLLSource

还想问下楼主大神关于这个问题,MPU6050的这个地址的寄存器和MPU9150的这个地址的寄存器的意义和功能可一样???请楼主告诉一个肯定的答案呀(地址:0x6B)

出0入0汤圆

发表于 2014-4-11 11:33:06 | 显示全部楼层
zksniper 发表于 2014-4-10 15:24
这是设置时钟源的,PLLSource

看了下寄存器描述,对比了下,完全一样,0x6B的最低3位确实是设置时钟的位

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

 楼主| 发表于 2014-4-11 12:53:25 | 显示全部楼层
billhsu 发表于 2014-4-11 10:50
就是通过磁来计算航向角的那个公式。

这个没错,程序我都验证过,缺陷是有,根本上的错误不会有。不然输出的欧拉角肯定不对

出0入0汤圆

 楼主| 发表于 2014-4-11 12:54:27 | 显示全部楼层
hfjydq 发表于 2014-4-11 11:23
还想问下楼主大神关于这个问题,MPU6050的这个地址的寄存器和MPU9150的这个地址的寄存器的意义和功能可一 ...

MPU6050和MPU9150通用,只不过9150多了个磁力计

出0入0汤圆

发表于 2014-4-11 13:29:16 | 显示全部楼层
zksniper 发表于 2014-4-11 12:53
这个没错,程序我都验证过,缺陷是有,根本上的错误不会有。不然输出的欧拉角肯定不对 ...

atan2(a,b)这个函数里面,是不是a与b要换一下位置?

出0入0汤圆

发表于 2014-4-11 14:08:37 | 显示全部楼层
感谢楼主分享,做个记号慢慢看!

出0入0汤圆

发表于 2014-4-11 14:58:42 | 显示全部楼层
zksniper 发表于 2014-4-11 12:54
MPU6050和MPU9150通用,只不过9150多了个磁力计

楼主绝对是大牛,品德也高尚

1.画圈的地方,为什么要加这个数呀?而且怎么确定就是400呀?   

2.
//定义不同测量范围的刻度因子
#define Accel_4_Scale_Factor    8192.0f

init_ax=((float)accel[0]) / Accel_4_Scale_Factor;           //单位转化成重力加速度的单位:g


这个刻度因子在哪确定是8192的,还有 把单位转化成重力加速度的单位:g    为什么按上面这个公式来计算,理论依据是什么呀

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2014-4-11 15:56:48 | 显示全部楼层
还请教大神一个问题,网上没找到,AK8975和HMC5883L的输出数据完全一样吗(包括输出的格式)?不知道是不是都是13位的补码,还有我想用你的校正AK8975的程序来校正HMC5883L,不知道可行的通

出0入0汤圆

发表于 2014-4-11 16:42:15 | 显示全部楼层
zksniper 发表于 2014-4-11 12:54
MPU6050和MPU9150通用,只不过9150多了个磁力计

大神,我能把你这种校正AK8975的方法直接用在HMC5883输出数据的校正上吗?还有你AK8975用了自校正了吗

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

 楼主| 发表于 2014-4-11 16:47:11 | 显示全部楼层
billhsu 发表于 2014-4-11 13:29
atan2(a,b)这个函数里面,是不是a与b要换一下位置?

这个根据你自己的定义来的,看你是定义磁力计x轴是机头,还是y轴是机头

出0入0汤圆

 楼主| 发表于 2014-4-11 16:50:23 | 显示全部楼层
hfjydq 发表于 2014-4-11 16:42
大神,我能把你这种校正AK8975的方法直接用在HMC5883输出数据的校正上吗?还有你AK8975用了自校正了吗 ...

你去找找加速度计和磁力计的校准资料看看吧,校准这块与自己的实际情况有关,别人的你用了效果只会更差,方法是通用的,而数据不是。

出0入0汤圆

发表于 2014-4-11 17:03:51 | 显示全部楼层
zksniper 发表于 2014-4-11 16:50
你去找找加速度计和磁力计的校准资料看看吧,校准这块与自己的实际情况有关,别人的你用了效果只会更差, ...

那你这个参数从哪得到的????

出0入0汤圆

发表于 2014-4-11 17:20:32 | 显示全部楼层
很好很牛逼,支持

出0入0汤圆

发表于 2014-4-11 20:00:32 | 显示全部楼层
mark                                   

出0入0汤圆

发表于 2014-4-14 09:15:48 | 显示全部楼层
zksniper 发表于 2014-4-11 16:50
你去找找加速度计和磁力计的校准资料看看吧,校准这块与自己的实际情况有关,别人的你用了效果只会更差, ...

我们加速度计用的都是一样的,为什么校正方法还不一样呢?磁力计可以去找找资料的,但加速度计校正不是一模一样的吗

出0入0汤圆

发表于 2014-4-14 10:20:15 | 显示全部楼层
你好!请教一个问题,我看到你的帖子,你也是用9150的,姿态采样能够到350-400,但是我看inv_mpu.c中master与bypass切换要3MS,请问你是怎么做到的?

出0入0汤圆

 楼主| 发表于 2014-4-14 10:26:28 | 显示全部楼层
hfjydq 发表于 2014-4-14 09:15
我们加速度计用的都是一样的,为什么校正方法还不一样呢?磁力计可以去找找资料的,但加速度计校正不是一 ...

每个传感器出场后的参数都不会完全一样

出0入0汤圆

 楼主| 发表于 2014-4-14 10:27:37 | 显示全部楼层
琅琊 发表于 2014-4-14 10:20
你好!请教一个问题,我看到你的帖子,你也是用9150的,姿态采样能够到350-400,但是我看inv_mpu.c中master ...

后来的代码中我已经改了,10ms采集一次磁力计数据即可,也就是说10ms内使用同一组磁力计数据,因为磁力计的output rate 本身也才几百hz

出0入0汤圆

发表于 2014-4-14 10:28:54 | 显示全部楼层
zksniper 发表于 2014-4-14 10:26
每个传感器出场后的参数都不会完全一样

呵呵 ,如果你这个方法对,我想厂家也不会把误差多大的产品卖出来的

出0入0汤圆

发表于 2014-4-14 10:47:50 | 显示全部楼层
zksniper 发表于 2014-4-14 10:27
后来的代码中我已经改了,10ms采集一次磁力计数据即可,也就是说10ms内使用同一组磁力计数据,因为磁力计 ...

哦,这也是个办法!谢谢昂

出0入0汤圆

发表于 2014-4-14 11:14:51 | 显示全部楼层
本帖最后由 琅琊 于 2014-4-14 11:16 编辑
zksniper 发表于 2014-4-14 10:27
后来的代码中我已经改了,10ms采集一次磁力计数据即可,也就是说10ms内使用同一组磁力计数据,因为磁力计 ...


10ms采集磁力计一次,采集还是需要6ms左右时间,此时间段IIC是被占用的,不能读6050了是吗?

出0入0汤圆

 楼主| 发表于 2014-4-14 12:16:30 | 显示全部楼层
琅琊 发表于 2014-4-14 11:14
10ms采集磁力计一次,采集还是需要6ms左右时间,此时间段IIC是被占用的,不能读6050了是吗? ...

这个跟I2C没关系,你可以把这6ms的时间看成是磁力计自己的准备时间,你只需要在10ms到来的时刻读一下就行了。其他时间干别的事

出0入0汤圆

 楼主| 发表于 2014-4-14 12:23:51 | 显示全部楼层
hfjydq 发表于 2014-4-14 10:28
呵呵 ,如果你这个方法对,我想厂家也不会把误差多大的产品卖出来的

误差的大小,取决于你觉的它是大是小,对于你来说这个误差可以接受,那么它就是小的,如果不可以接受,极端点,哪怕1个LSB的误差你都要去校准,所以校不校准,或者用什么方法校准,取决于你和你的应用的接受程度,我的方法是大众化方法,做起来简单,理解起来也简单,精度肯定不高,但是我觉得目前够用了。

芯片硬件上的差异比你想象的大的多,造芯片的是人和机器,焊接的也是人和机器,这就是误差来源。

出0入0汤圆

发表于 2014-4-14 13:51:56 | 显示全部楼层
zksniper 发表于 2014-4-14 12:16
这个跟I2C没关系,你可以把这6ms的时间看成是磁力计自己的准备时间,你只需要在10ms到来的时刻读一下就行 ...

我的意思是在这6ms内不能够读取6050了,因为读取8975时必须开启bypass模式,此时是不能够读取6050,可对?

出0入0汤圆

发表于 2014-4-14 15:11:37 | 显示全部楼层
本帖最后由 hfjydq 于 2014-4-14 15:14 编辑
zksniper 发表于 2014-4-14 12:23
误差的大小,取决于你觉的它是大是小,对于你来说这个误差可以接受,那么它就是小的,如果不可以接受,极 ...


好吧,这样说也对,想问下你的yaw精确到多少度左右?1度以内吗(这个AHRS算法,不上电机,手动的转动的时候)?

出0入0汤圆

 楼主| 发表于 2014-4-14 15:42:35 | 显示全部楼层
琅琊 发表于 2014-4-14 13:51
我的意思是在这6ms内不能够读取6050了,因为读取8975时必须开启bypass模式,此时是不能够读取6050,可对 ...

可以读,bypass不影响别的,帖子里已经说过了。你找找吧

出0入0汤圆

发表于 2014-4-14 16:01:17 | 显示全部楼层
把整个贴读了一遍,既然没有人遇到和我一样的问题,我是被深深的伤到了!  第一次移植_spetrel的,打印串口一直出现
然后移植楼主的 出现好多警告
我用的是STM32F103VET6  +MPU9150模块,

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

 楼主| 发表于 2014-4-14 16:05:25 | 显示全部楼层
zengan007 发表于 2014-4-14 16:01
把整个贴读了一遍,既然没有人遇到和我一样的问题,我是被深深的伤到了!  第一次移植_spetrel的,打印串口 ...

大致看了下,没看懂,这个东西跟编译器也有关系,优化等级,警告等级等等,如果不太爽,可以好好调一下,能用的话,不调也行。

出0入0汤圆

发表于 2014-4-14 16:11:33 | 显示全部楼层
zksniper 发表于 2014-4-14 16:05
大致看了下,没看懂,这个东西跟编译器也有关系,优化等级,警告等级等等,如果不太爽,可以好好调一下, ...

这么快就回复,楼主真好人!

出0入0汤圆

发表于 2014-4-14 16:54:13 | 显示全部楼层
zksniper 发表于 2014-4-14 15:42
可以读,bypass不影响别的,帖子里已经说过了。你找找吧

你的意思是不关闭bypass?

出0入0汤圆

发表于 2014-4-14 16:56:54 | 显示全部楼层
楼主大神,我移植你的AHRSUpdate算法的程序,终于移植成功了,好兴奋哦,这是复位以后三个角度值,其中roll和pitch很准的,就是yaw,复位后从0°一路直飙到17.4°左右,就停下来了,磁力计用的HMC5883L,也校正了,就知道啥原因,为什么每次都是yaw出问题,咋办呀大神

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2014-4-14 22:03:35 | 显示全部楼层
billhsu 发表于 2014-4-10 22:15
楼主,你的航向角公式是不是错了啊。atan2的分子是不是该分母换一下啊?

你可得到正确的结果了呀??、我在公司的时候就yaw不正确,现在回家后发现全乱了

出0入0汤圆

发表于 2014-4-14 22:56:57 | 显示全部楼层
zksniper 发表于 2013-9-2 17:48
这个当初做板子确实没有考虑到。

就先拿这个板子当个测试板来用吧,下次懂的多了直接一步到位。

不知道这个程序可有人移植成功,我是有点失望了……

出0入0汤圆

 楼主| 发表于 2014-4-15 09:18:05 | 显示全部楼层
琅琊 发表于 2014-4-14 16:54
你的意思是不关闭bypass?

bypass不用关闭,流程:
初始化时开启bypass,关闭I2C_MASTER,开启single measurement

后面使用时,
先读一次Compass_ST1,
如果=1,
则说明compass数据准备好了,可以读取数据了,读取完成后再开启single measurement,因为AK8975读取一次完成后会自动跳到power down mode(好像是这个);
如果没准备好,就使用上一次的compass数据


基本上开启一次single measurement,大概需要7ms数据才会准备好,如果在7ms内读取数据,会有出错的几率。

出0入0汤圆

发表于 2014-4-15 09:30:51 | 显示全部楼层
zksniper 发表于 2014-4-15 09:18
bypass不用关闭,流程:
初始化时开启bypass,关闭I2C_MASTER,开启single measurement

恩,谢谢!这样子太好了!!

出0入0汤圆

 楼主| 发表于 2014-4-15 09:36:58 | 显示全部楼层
hfjydq 发表于 2014-4-14 16:56
楼主大神,我移植你的AHRSUpdate算法的程序,终于移植成功了,好兴奋哦,这是复位以后三个角度值,其中roll ...

你上电后保持板子水平不动,看下初始化时得到的yaw,和你经过AHRSupdate输出的yaw是否一致?如果不一致,说明某个环节出错了,如果一致,并且yaw只是偏一点,并且可以按照你的旋转而正确改变,那么,才是校准的问题。或者有强磁场干扰。

看下你读取的accel gyro mag的数据都对不对,传递到AHRSupdate之前的单位有没有转化好,全局和局部参数有没有重复定义,导致参数被错误覆盖的?

出0入0汤圆

发表于 2014-4-15 10:02:39 | 显示全部楼层
zksniper 发表于 2014-4-11 16:47
这个根据你自己的定义来的,看你是定义磁力计x轴是机头,还是y轴是机头

仔细想了一下,楼主你是对的,或者可以说是绕X轴旋转是ROLL还是PITCH

出0入0汤圆

发表于 2014-4-15 10:03:13 | 显示全部楼层
hfjydq 发表于 2014-4-14 22:03
你可得到正确的结果了呀??、我在公司的时候就yaw不正确,现在回家后发现全乱了 ...

楼主的观点是对的。你要注意到底哪个是俯仰角,哪个是横滚角!

出0入0汤圆

发表于 2014-4-15 10:44:46 | 显示全部楼层
zksniper 发表于 2014-4-15 09:36
你上电后保持板子水平不动,看下初始化时得到的yaw,和你经过AHRSupdate输出的yaw是否一致?如果不一致, ...

反复测试,roll和pitch就是很准,绝对能达到1°以内的误差,而且能跟上我的旋转,yaw越来越离谱,我现在的直觉是加速度计和陀螺仪肯定没问题,我觉得问题就出在磁力计各轴数据的校正和磁力计对yaw校正,感觉肯定是这2个方面出了问题,和数据类型呀什么的半毛钱没关系

出0入0汤圆

发表于 2014-4-15 10:48:05 | 显示全部楼层
billhsu 发表于 2014-4-15 10:03
楼主的观点是对的。你要注意到底哪个是俯仰角,哪个是横滚角!

我连这还分不清吗???我定义的x轴是rol

/*******************************************************************************
* Function Name  : init_quaternion
* Description    : 算出初始化四元数q0 q1 q2 q3.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void init_quaternion(void)
{
        u8 i;
        tg_HMC5883L_TYPE hmc5883l;
        signed short int accel[3];
        float init_Yaw, init_Pitch, init_Roll;
       
        if(!IIC_Read(MPU6050_Addr, Accel_Xout_H, 6, data_write))
        {
                accel[0]=((( signed short int)data_write[0])<<8) | data_write[1];
                accel[1]=((( signed short int)data_write[2])<<8) | data_write[3];
                accel[2]=((((signed short int)data_write[4])<<8) | data_write[5]) + Accel_Zout_Offset;
               
                init_ax=((float)accel[0]) / Accel_4_Scale_Factor;           //单位转化成重力加速度的单位:g
                init_ay=((float)accel[1]) / Accel_4_Scale_Factor;
                init_az=((float)accel[2]) / Accel_4_Scale_Factor;
               
                for(i=0;i<5;i++)   //第一次读取的compsaa数据是错的,因此要多读几次保证以后数据正确,芯片bug
                {
                        HMC5883L_Init();   
                        delay_ms(10);                  
                        HMC5883L_MultRead(&hmc5883l);   //读磁阻仪数据(速度:慢, ms级延时过程)
                        //进行x y轴的校准,未对z轴进行校准,参考MEMSense的校准方法
                        init_mx =hmc5883l.hx;                                               
                        init_my =hmc5883l.hy;
                        init_mz =hmc5883l.hz;
                }
               
                //陀螺仪x轴为前进方向
                init_Roll  = atan2(init_ay, init_az);
                init_Pitch = -asin(init_ax);              //init_Pitch = asin(ax / 1);      
                init_Yaw   = -atan2(init_mx*cos(init_Roll) + init_my*sin(init_Roll)*sin(init_Pitch) + init_mz*sin(init_Roll)*cos(init_Pitch),
                                  init_my*cos(init_Pitch) - init_mz*sin(init_Pitch));                       //atan2(mx, my);
                q0 = cos(0.5*init_Roll)*cos(0.5*init_Pitch)*cos(0.5*init_Yaw) + sin(0.5*init_Roll)*sin(0.5*init_Pitch)*sin(0.5*init_Yaw);  //w
                q1 = sin(0.5*init_Roll)*cos(0.5*init_Pitch)*cos(0.5*init_Yaw) - cos(0.5*init_Roll)*sin(0.5*init_Pitch)*sin(0.5*init_Yaw);  //x   绕x轴旋转是roll
                q2 = cos(0.5*init_Roll)*sin(0.5*init_Pitch)*cos(0.5*init_Yaw) + sin(0.5*init_Roll)*cos(0.5*init_Pitch)*sin(0.5*init_Yaw);  //y   绕y轴旋转是pitch
                q3 = cos(0.5*init_Roll)*cos(0.5*init_Pitch)*sin(0.5*init_Yaw) - sin(0.5*init_Roll)*sin(0.5*init_Pitch)*cos(0.5*init_Yaw);  //z   绕z轴旋转是Yaw
               
                init_Roll  = init_Roll * 57.295780;         //弧度转角度
                init_Pitch = init_Pitch * 57.295780;
                init_Yaw   = init_Yaw * 57.295780;
                if(init_Yaw < 0)          //将Yaw的范围转成0-360
                {
                        init_Yaw = init_Yaw + 360;
                }      
                if(init_Yaw > 360)
                {
                        init_Yaw = init_Yaw - 360;
                }             
        }
}




void AHRSupdate(float gx, float gy, float gz, float ax, float ay, float az, float mx, float my, float mz)
{
        float norm, halfT;
        float hx, hy, hz, bz, bx;
        float vx, vy, vz, wx, wy, wz;
        float ex, ey, ez;
        float Pitch, Roll, Yaw;
       
        /*方便之后的程序使用,减少计算时间*/
        //auxiliary variables to reduce number of repeated operations,
        float q0q0 = q0*q0;
        float q0q1 = q0*q1;
        float q0q2 = q0*q2;
        float q0q3 = q0*q3;
        float q1q1 = q1*q1;
        float q1q2 = q1*q2;
        float q1q3 = q1*q3;
        float q2q2 = q2*q2;   
        float q2q3 = q2*q3;
        float q3q3 = q3*q3;
       
        /*归一化测量值,加速度计和磁力计的单位是什么都无所谓,因为它们在此被作了归一化处理*/        
        //normalise the measurements
        norm = invSqrt(ax*ax + ay*ay + az*az);      
        ax = ax * norm;
        ay = ay * norm;
        az = az * norm;
        norm = invSqrt(mx*mx + my*my + mz*mz);         
        mx = mx * norm;
        my = my * norm;
        mz = mz * norm;         
       
        /*从机体坐标系的电子罗盘测到的矢量转成地理坐标系下的磁场矢量hxyz(测量值),下面这个是从飞行器坐标系到世界坐标系的转换公式*/
        //compute reference direction of flux
        hx = 2*mx*(0.5 - q2q2 - q3q3) + 2*my*(q1q2 - q0q3) + 2*mz*(q1q3 + q0q2);
        hy = 2*mx*(q1q2 + q0q3) + 2*my*(0.5 - q1q1 - q3q3) + 2*mz*(q2q3 - q0q1);
        hz = 2*mx*(q1q3 - q0q2) + 2*my*(q2q3 + q0q1) + 2*mz*(0.5 - q1q1 - q2q2);
       
        /*计算地理坐标系下的磁场矢量bxyz(参考值)。
        因为地理地磁水平夹角,我们已知是0度(抛去磁偏角的因素,固定向北),我定义by指向正北,所以by=某值,bx=0
        但地理参考地磁矢量在垂直面上也有分量bz,地球上每个地方都是不一样的。
        我们无法得知,也就无法用来融合(有更适合做垂直方向修正融合的加速度计),所以直接从测量值hz上复制过来,bz=hz。
        磁场水平分量,参考值和测量值的大小应该是一致的(bx*bx) + (by*by)) = ((hx*hx) + (hy*hy))。
        因为bx=0,所以就简化成(by*by)  = ((hx*hx) + (hy*hy))。可算出by。这里修改by和bx指向可以定义哪个轴指向正北*/
        bx = sqrtf((hx*hx) + (hy*hy));
        //by = sqrtf((hx*hx) + (hy*hy));
        bz = hz;        
       
        // estimated direction of gravity and flux (v and w),下面这个是从世界坐标系到飞行器坐标系的转换公式(转置矩阵)
        vx = 2*(q1q3 - q0q2);
        vy = 2*(q0q1 + q2q3);
        vz = q0q0 - q1q1 - q2q2 + q3q3;
       
        /*我们把地理坐标系上的磁场矢量bxyz,转到机体上来wxyz。
        因为bx=0,所以所有涉及到bx的部分都被省略了。同理by=0,所以所有涉及到by的部分也可以被省略,这根据自己定义那个轴指北有关。
        类似上面重力vxyz的推算,因为重力g的az=1,ax=ay=0,所以上面涉及到gxgy的部分也被省略了
        你可以看看两个公式:wxyz的公式,把by换成ay(0),把bz换成az(1),就变成了vxyz的公式了(其中q0q0+q1q1+q2q2+q3q3=1)。*/
        wx = 2*bx*(0.5 - q2q2 - q3q3) + 2*bz*(q1q3 - q0q2);
        wy = 2*bx*(q1q2 - q0q3) + 2*bz*(q0q1 + q2q3);
        wz = 2*bx*(q0q2 + q1q3) + 2*bz*(0.5 - q1q1 - q2q2);
//        wx = 2*by*(q1q2 + q0q3) + 2*bz*(q1q3 - q0q2);
//        wy = 2*by*(0.5 - q1q1 - q3q3) + 2*bz*(q0q1 + q2q3);
//        wz = 2*by*(q2q3 - q0q1) + 2*bz*(0.5 - q1q1 - q2q2);
       
        //现在把加速度的测量矢量和参考矢量做叉积,把磁场的测量矢量和参考矢量也做叉积。都拿来来修正陀螺。
        // error is sum of cross product between reference direction of fields and direction measured by sensors
        ex = (ay*vz - az*vy) + (my*wz - mz*wy);
        ey = (az*vx - ax*vz) + (mz*wx - mx*wz);
        ez = (ax*vy - ay*vx) + (mx*wy - my*wx);
       
        //   // integral error scaled integral gain
        //   exInt = exInt + ex*Ki;               
        //   eyInt = eyInt + ey*Ki;
        //   ezInt = ezInt + ez*Ki;
        //   // adjusted gyroscope measurements
        //   gx = gx + Kp*ex + exInt;
        //   gy = gy + Kp*ey + eyInt;
        //   gz = gz + Kp*ez + ezInt;
       
        halfT=GET_NOWTIME();                //得到每次姿态更新的周期的一半
       
        if(ex != 0.0f && ey != 0.0f && ez != 0.0f)      //很关键的一句话,原算法没有
        {
                // integral error scaled integral gain
                exInt = exInt + ex*Ki * halfT;                           //乘以采样周期的一半
                eyInt = eyInt + ey*Ki * halfT;
                ezInt = ezInt + ez*Ki * halfT;
                // adjusted gyroscope measurements
                gx = gx + Kp*ex + exInt;
                gy = gy + Kp*ey + eyInt;
                gz = gz + Kp*ez + ezInt;
        }         
       
        // integrate quaternion rate and normalise,四元数更新算法
        q0 = q0 + (-q1*gx - q2*gy - q3*gz)*halfT;
        q1 = q1 + (q0*gx + q2*gz - q3*gy)*halfT;
        q2 = q2 + (q0*gy - q1*gz + q3*gx)*halfT;
        q3 = q3 + (q0*gz + q1*gy - q2*gx)*halfT;  
       
        // normalise quaternion
        norm = invSqrt(q0*q0 + q1*q1 + q2*q2 + q3*q3);
        q0 = q0 * norm;       //w
        q1 = q1 * norm;       //x
        q2 = q2 * norm;       //y
        q3 = q3 * norm;       //z
       

        Yaw   =  atan2(-2 * (q0 * q3 + q1 * q2) , q0*q0+q1*q1-q2*q2-q3*q3) * 57.3;                        //yaw,绕z轴转动
        Pitch =  asin ( 2 * (q1 * q3 - q0 * q2)) * 57.3;                                                        // pitch,绕y轴转动
        Roll  =  atan2( 2 * (q0 * q1 + q2 * q3) , 1 - 2 * (q1 * q1 + q2 * q2)) * 57.3;        // roll,绕x轴转动l

出0入0汤圆

发表于 2014-4-16 10:17:10 | 显示全部楼层
楼主大神,我现在用椭圆拟合的方法校正了磁力计,现在水平静止的时候,三个角度都比较好了,但动起来yaw就飘起来了,最大的时候能飘30°,是不是椭圆拟合在动起来的时候还是不行呀?需要椭球拟合校正磁力计才行呀??你会椭球拟合的校正方法吗?

出0入0汤圆

发表于 2014-4-16 14:50:36 | 显示全部楼层
楼主大神,请教你一个问题,圈出来的地方,这些公式是将单位转化成 m/s²?????还是转换成重力加速度g(g=9.8m/s²)的倍数???

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2014-4-21 13:28:40 | 显示全部楼层
来拜谢楼主的,跟着楼主学了很多知识,谢谢楼主的无私奉献,好人一生平安

出0入0汤圆

发表于 2014-4-23 16:20:47 | 显示全部楼层
想问下楼主有没有遇到这样的问题,就是在转动传感器时,得出的欧拉角先是增大,然后慢慢恢复到正确的角度?举个例子:比方说此时yaw=90,转动45之后应该为45,但是这个转动的过程中,yaw先是增大到110然后再慢慢恢复到45

出0入0汤圆

发表于 2014-4-25 20:31:37 | 显示全部楼层
先收藏了

出0入0汤圆

发表于 2014-4-29 08:37:16 | 显示全部楼层
楼主,再请教你一个问题哦,如何根据姿态角把重力加速度分解到机体各轴呢?我定义的是X轴指向北方,请教了,想了好久也没想出如何计算,拜谢了

出0入0汤圆

发表于 2014-4-30 09:48:34 | 显示全部楼层
学习啦,谢谢楼主分享

出0入0汤圆

发表于 2014-5-15 09:40:24 | 显示全部楼层
请教下楼主,你的MPU的采样时间是多少?

出0入0汤圆

发表于 2014-5-15 11:52:35 | 显示全部楼层
用的是互补滤波

出0入0汤圆

发表于 2014-5-19 19:33:03 | 显示全部楼层
请问,这里的ACCEL_SCALE_FATOR是怎么确定的?

出0入0汤圆

 楼主| 发表于 2014-5-20 09:10:47 | 显示全部楼层
caiming1234567 发表于 2014-5-19 19:33
请问,这里的ACCEL_SCALE_FATOR是怎么确定的?

mpu9150的datesheet里,单位LSB/g

出0入0汤圆

发表于 2014-5-20 09:41:38 | 显示全部楼层
zksniper 发表于 2014-5-20 09:10
mpu9150的datesheet里,单位LSB/g

也就是说我初始化加速度初始化量程为4g,那么accel_scale_fator =1/ 4096*4*g吗?

出0入0汤圆

 楼主| 发表于 2014-5-20 10:26:49 | 显示全部楼层
caiming1234567 发表于 2014-5-20 09:41
也就是说我初始化加速度初始化量程为4g,那么accel_scale_fator =1/ 4096*4*g吗?

量程4g对应的accel_scale_fator=8192 LSB/g

水平静止放置9150,那么在4g量程下,az的读数理论值就是8192*1,这个“1”的单位是g,az的单位是LSB

出0入0汤圆

发表于 2014-5-26 12:56:53 | 显示全部楼层
我也发现了一些问题 DMP组成P R角 Y是原始DMP+5883L组合的 发现总是乱跳..

出0入0汤圆

发表于 2014-5-26 13:01:18 | 显示全部楼层
hfjydq 发表于 2014-4-8 10:24
楼主,在看你的程序,讲的已经很细了,但还是有一些地方不太明白,请问一下你的这个程序yaw准吗?因为你用 ...

你的问题跟我差不多.都是5883导致的 .你的读取函数是咋样的.能发来我看看不werty778899@126.com

出0入16汤圆

发表于 2014-6-10 10:47:24 | 显示全部楼层
很好,谢谢分享

出0入0汤圆

发表于 2014-6-10 13:27:54 | 显示全部楼层
大神在吗,我现在在做加速度计和陀螺仪数据的融合算法,有一些问题想请教你,1414797521,加个QQ好友行吗,折腾了好多天了,快疯了。谢了。

出0入0汤圆

发表于 2014-6-16 10:28:52 | 显示全部楼层
关于这个定时器的注释,有很多疑问,难道这个注释是乱写的吗???1MHz,计数5000是5ms吧,怎么会是500ms??,那个CNT,是读CNT,应该是低16位是读出的数,却写着高16位,什么情况????

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2014-6-16 11:07:16 | 显示全部楼层
zksniper 发表于 2013-9-6 13:25
先调一下Kp和Ki这两个参数,看有没有效果。

不行的话,还有halfT这个参数,要用Timer来计时,比如你一次 ...

是不是说错了???我实测觉得这个halfT应该是2s左右吧,那个float GET_NOWTIME(void)函数,获得的时间单位为S吧,不是毫秒吧??我觉得楼主这2个定时器的函数注释严重有问题

出0入0汤圆

 楼主| 发表于 2014-6-16 13:48:18 | 显示全部楼层
本帖最后由 zksniper 于 2014-6-16 13:49 编辑
hfjydq 发表于 2014-6-16 10:28
关于这个定时器的注释,有很多疑问,难道这个注释是乱写的吗???1MHz,计数5000是5ms吧,怎么会是500ms? ...


这几行注释都不是我写的,改程序的时候难免有注释漏改的情况,有时候程序改完了,注释没修改,都会造成这种情况,像这种情况,直接参考代码

那个systick,分频是108,计一个数是1us,5000个数当然是5ms
那个TIM4->CNT就是个16位的寄存器,写高16位跟写低16位有毛区别?
GET_NOWTIME的单位,看下TIM4计一个数是多久,再除个2000000,算算单位是s还是ms,我记得是s
至于halfT你觉得有2s,你可以看看你代码哪个地方有问题,4s一次姿态解算,还怎么玩?测得时候用减法,刨去printf的时间,这个最耗时。

太细节的东西难免有疏忽,新版本的代码这些都已经更正过来了。只是PID部分还需要调整,放上来也没意义。

出0入0汤圆

 楼主| 发表于 2014-6-16 14:24:19 | 显示全部楼层
2014年6月16日更新:
声明:以下更新只针对新手,为了让新手对整个四轴有个大致全面的认识,欢迎前辈和新手指出不足和错误之处。

想了想还是先把代码放上来吧,好久没更新了,主楼位的代码大部分自己也不满意,新代码做了大量修改和增加,包含了完整的姿态解算和PID控制部分,现将整个代码放上来,仅供参考,代码的PID部分是标准的PID,可以飞,但是操控性等于0,或者说需要很小心很有经验的去操控,不要拿来移植完了就用,后果就是去淘宝再来500块钱的材料。原因是D项是只对角度进行微分,操控起来四轴的动作太猛,之所以先这么做,也是为了验证大家的说法和增加自己的体验,一般把D项改为对角速度的微分,手感就好很多了,至少回方向时四轴不会太猛。

先上新版图片,大众化配置,没啥好说的:










以下是喜闻乐见的螺丝没拧紧,也没用螺纹胶的后果,目前已修好:




下面说一些乱七八糟的东西,但是个人感觉很有用的东西,包括PID、整机、代码等等。

PID分两种位置式和增量式,我采用的是位置式,将Ki和Kd用Ti和Td的形式来表达,并带入到式2-3中,ek=角度的期望-传感器输出的角度,所用的PID三个参数是:Kp、Ti、Td。公式如图所示:


四轴PID控制的目的就是将接收到的遥控的控制信号(一般有油门THR、升降舵ELE(对应pitch)、副翼Ail(对应roll)、方向舵RUD(对应yaw))与飞控板本身计算得出pitch、roll、yaw做比较,分别得出它们之间的误差值,然后将Kp、Ti、Td与这个误差值结合得出PID输出(PID_pitch、PID_roll或者PID_yaw),再将这三个PID输出与油门结合在一起算出送到每一个电调的PWM数值,从而控制每一个电机的转动。

那么我们就需要考虑三个问题,这三个问题都是围绕《让自己的四轴怎样转动》:

1.       飞行时是使用“+”模式还是使用“x”模式

2.       四个电机分别该如何旋转,是逆时针还是顺时针

3.       每个电机该怎样旋转才能让我们的四轴上升、下降、左翻、右翻、上仰、俯冲、左转头或者右转头

对于第一个问题来说:

一般“+”模式比较好操作,也比较好调节PID的那三个参数,而“x”模式飞行起来比较灵活,可以做很多复杂动作,但是比较难操作,这里我用的是“x”模式,对于新手来说,包括我,虽然“x”模式难一些,不过最多也就是需要时间来学习和熟练罢了,其实也没什么难的。

对于第二个问题:
首先要确定飞控板的xyz轴正方向如何放置,然后确定4个电机的旋转方向分别是什么,我定义的方式如下图,Y正方向为四轴前进方向:

M1、M2、M3、M4分别为4个电机,其中M1和M4顺时针旋转,M2和M3逆时针旋转。

对于第三个问题:

还是看上图,我定义三点:

一.xyz轴的正方向为:y指向正北,x指向东,z指向天;

二.绕y旋转是roll,绕x旋转是pitch,绕z旋转是yaw;

三.Yaw北偏西为正,pitch往上为正,roll“右翼”下沉为正。
令:“+”表示增加该电机的旋转速度,“-”表示减小该电机的旋转速度,那么“x”模式下的控制规律如下:


最后得出每个电机需要的PWM输出计算公式:


其中Limit_PWMOUT函数是限制PWM的输出,根据电调的PWM占空比来确定。

还有一点需要注意的,就是桨叶的安装,桨叶是分正反浆的,通俗的说,安装时要保证4个桨叶转动时都是往下吹风的。

四轴零件之间的接线与简单说明:
4个电调的正负极需要并联(红色连一起,黑色连1一起),并接到电池的正负极上;
电调3根黑色的电机控制线,连接电机;
电调有个BEC输出,共3根线,红、黑线用于输出5v的电压,给飞行控制板供电,另外一根线用于接收飞行控制板的PWMout信号;
遥控接收器连接在飞行控制器的PWMin上,输出遥控信号给飞控板,并同时从飞行控制板上得到5v供电;

关于PWMin和PWMout:

对于我的天地飞7通遥控+WFT07接收机来说,遥控发送给接收机的信号是PPM,而接收机输出的信号是标准的PWM。

对于接收机来说,我们只需要关心它输出的高电平时间,也就是PWMin,不用管占空比,因此TIM_Period设定为 0xFFFF。我的WFT07接收机的PWM周期是20ms,高电平是1ms~2ms。

对于给电调的输入来说,也就是PWMout,要确定其占空比,一般根据自己的电调来确定这个占空比,我用的是好盈天行者20A,频率为50~432hz,所以我的PWM周期设定为2.5ms 频率400hz,高电平持续时间限制在0.875ms~2.0ms,高电平一般在周期的20%~80%。

如何将遥控的PWMin转化为期望的角度expect:

  先看一个公式:e(t)=expect – measured,这是PID中的误差e(t),等于遥控期望值减去传感器的测量值。

而将遥控的PWMin转化为期望的角度expect所达到的目的就是将PWMin转化为expect,使expect的范围大小(不是单位,PWMin的单位可以看成已经是角度单位了)与measured的对应起来,并限制expect的范围,对新手来说好操控。
至于转化,就是将PWMin通过一些加减乘除限定在一定范围内,比如我将PWMin(Motor_Ail、Motor_Ele、Motor_Rud)限定在-25度到+25度内,而Motor_Thr保持原来的范围,暂不做限定,可根据具体操作手感来做限定,如下图,其中AilMiddle、EleMiddle、RudMiddle均为1500:


关于对PWMin的滤波:

         TIM2_ICInitStructure.TIM_Channel =TIM_Channel_4;

       TIM2_ICInitStructure.TIM_ICPolarity= TIM_ICPolarity_Rising;    //先上升沿捕获

       TIM2_ICInitStructure.TIM_ICSelection= TIM_ICSelection_DirectTI; //映射到TI1上

       TIM2_ICInitStructure.TIM_ICPrescaler= TIM_ICPSC_DIV1;  //配置输入分频,不分频

       TIM2_ICInitStructure.TIM_ICFilter = 0x0B;//IC1F=1010滤掉1us以下脉冲宽度的干扰,避免意外进入中断6/(108Mhz/16)=0.9us

       TIM_ICInit(TIM2,&TIM2_ICInitStructure);

将TIM_ICFilter设置为0x0B,滤掉1us以下脉冲干扰,防止误进PWMin中断,避免将干扰信号当作PWMin来接收。

下面上代码:


代码是针对Gigadevice公司的GD32F103VCT6这款芯片的,系统时钟108M,修改完系统时钟后可直接移植到STM32F103VCT6上,代码是在主楼位代码的基础上修改了很多东西,也添加了很多东西,并且代码都是经过我自己验证过的,而且已经能飞了的。
新的代码包含了:
1.磁力计现场校准,代码直接完成,不需要PC干预。换个地方飞不用再带个电脑做校准了。
2.陀螺仪零偏自校准
4.加速度计零偏和灵敏度校准
4.代码时间片管理,姿态融合500Hz,PID控制200Hz,com通信10Hz
5.位置式PID控制,控制参数采用kp,Ti,Td,标准PID,测试用
6.固定航向模式。日后加入可控航向。
7.串口在线调试,不够方便,但是能用,支持在线参数保存和读取,采用GD32F103内部Flash来保存参数,不用外扩存储芯片,也方便调试PID参数和磁力计校准,自用的话可放心尽情的擦写。
8.飞行模式:x模式
9.开启加速度计低通滤波98Hz

在测试过程中如果发现代码有问题或纰漏,请指出。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2014-6-17 13:59:09 | 显示全部楼层
zksniper 发表于 2014-6-16 14:24
2014年6月16日更新:
声明:以下更新只针对新手,为了让新手对整个四轴有个大致全面的认识,欢迎前辈和新手 ...

楼主终于重出江湖了,想咨询个问题,加速度计、陀螺仪、还有磁力计输出的原始数据是什么单位?或者如何转化成他们所代表的物理单位,比如加速度计原始数据如何转换成m/S²   

出0入0汤圆

发表于 2014-6-21 09:13:05 | 显示全部楼层
楼主很有心

出0入0汤圆

 楼主| 发表于 2014-6-22 16:28:29 | 显示全部楼层
hfjydq 发表于 2014-6-17 13:59
楼主终于重出江湖了,想咨询个问题,加速度计、陀螺仪、还有磁力计输出的原始数据是什么单位?或者如何转 ...

加速度计、陀螺仪、磁力计的原始单位都是LSB,与灵敏度因子结合运算可得到具体的实际单位

出0入0汤圆

发表于 2014-6-22 17:07:53 | 显示全部楼层
姿态融合和算法这一块还真是有的玩。

出0入0汤圆

发表于 2014-6-23 10:53:28 | 显示全部楼层
zksniper 发表于 2014-6-22 16:28
加速度计、陀螺仪、磁力计的原始单位都是LSB,与灵敏度因子结合运算可得到具体的实际单位 ...

谢谢  明白了

出0入0汤圆

发表于 2014-6-23 16:00:28 | 显示全部楼层
楼主您好:

能不能讲解一下你的地磁标定方法,你提供的E文资料看不明白......先行感谢啦!

出0入0汤圆

发表于 2014-7-20 14:22:10 | 显示全部楼层
谢谢楼主  赞一个
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-23 17:56

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表