博士
最后登录1970-1-1
在线时间 小时
注册时间2015-10-25
|
本帖最后由 望着你发槑 于 2016-11-18 11:36 编辑
SORRY火哥,上个月干其他事去了,现在继续弄小车。
重新写了一下程序,排版好了一点。
从原来的一阶互补滤波升级到卡尔曼滤波
卡尔曼滤波我还不熟练,现在的参数还不是很好,有过冲,而且收敛不够快,先分享程序,然后继续调试
但是比一阶互补滤波还是有一个好处,就是将陀螺仪的常值偏差也作为一个状态量,就不用自己去调整了。
一阶互补滤波不减这个常值偏差的话会有稳态误差,卡尔曼滤波没有。
蓝绿色的线是加速度计直接算出来的角度,紫色的线是一阶互补滤波算出来的,黄色的线是卡尔曼滤波算出来的角度。
上位机用的匿名上位机。
由于单片机没有矩阵运算,所以我自己在草稿纸上算了之后腾上来的。
但是在状态估计校正的最后一行,更新常值偏差的时候,按照我自己演算的应该是加等,但是这样就不收敛,常值偏差会越来越大,所以我尝试着变成减等,没想到就行了。
有没有大神能解答一下。
我参考的那篇论文在附件里面。
Bluetooth is coming
直接使用笔记本自带的蓝牙就行了
火哥这个蓝牙叫做SPP-CA,配对码是1234,使用蓝牙连接之后再设备管理器里面可以看到两个串口
虽然写着一个传出一个传入,不过上位机连接COM7还是能收到倾角信息
火哥的平衡车上蓝牙连接的UART4,没见过这个,就重映射到USART3上面啦,然后把上传倾角的串口由1改成3就OK了
- USART_SendData(USART3, (uint8_t)ch);
- while (USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);
复制代码 就像这样,然后就不用连线了。正好我的笔记本年事已高,左边两个USB已经坏了一个,现在连着USB集线器在用,有蓝牙就再也不需要了。
对了,我还试过那个平衡小车的app,那个也挺不错的,后期用手机控制小车移动就靠它了。这个串口的波特率设置的9600,慢了一点,因为app是这么多,我又不会改手机app,就只有写程序将就一下他了。
现在看着上位机的画图能看得出一阶互补滤波比卡尔曼滤波要滞后一点点。
发现了一个了不得的问题,蓝牙连接小车不是产生了两个端口吗,我现在需要用一个串口调试助手连接传出的那个COM8口,在用上位机连接传入的COM7口才能正常工作。直接使用上位机连COM7,软件要死机,不是单片机死机,奇了怪了。
手机APP弄好了,通信协议上面把倾角和电量百分比的顺序搞反了。
就是C和D反了,我们自己写的时候注意就行了。
单独开了一个定时器来测试现在就算倾角之类的花了多长时间,没想到还真发现问题了。- TIM2->CNT=0;
- TIM_Cmd(TIM2, ENABLE);
- TIM_Cmd(TIM2, DISABLE);
- printf("\r\n %d",TIM2->CNT);
复制代码 就用四行程序可以测出他们之间的程序回花多少时间
现在就只有读取角度和解算角度和发送角度给上位机就花了6700多微妙,也就是6毫秒以上了,原来的5毫秒定时器就不合适。
我没有直接把程序写在定时器里面的原因其中之一就是这个。
简单验证了一下,如果进入定时器的时候flag依然等于1的话,说明主程序都还没跑完。
确实是,所以我把控制周期改成10ms了。
调了一下电机的PWM,由于MPU6050没有地磁计,不能精确判断偏航角,原来的小车由于左右轮的转速和力矩差别总是容易打转,所以花了点心思调这个。使用串口打出不同pwm对应的转速,然后拟合了一下,尽量把左右调的一样。
直接上图
第一幅图是原始的数据,二三副图是正方向和负方向分开拟合的。
现在还有一个小瑕疵,就是正反转的时候略微有一点不对应,就是正负象限合起来还不是偶函数,以后再调。或者大家也可以调,现在效果应该比以前好了。- void Dongqilai(int16_t pwm)
- {
- uint16_t pwm_l,pwm_r;
- if(pwm<0)
- {
- MotorA_DirCtl(-1);
- MotorB_DirCtl(-1);
- pwm_l=300-pwm;
- pwm_r=pwm_l+70;
- if(pwm_l>6000) pwm_l=6000;
- if(pwm_r>6000) pwm_r=6000;
- TIM_SetCompare1(TIM1,pwm_r);//MOTOB
- TIM_SetCompare4(TIM1,pwm_l);//MOTOA
- }
- else if(pwm==0)
- {
- MotorA_DirCtl(0);
- MotorB_DirCtl(0);
- TIM_SetCompare1(TIM1,0);//MOTOB
- TIM_SetCompare4(TIM1,0);//MOTOA
- }
- else
- {
- MotorA_DirCtl(1);
- MotorB_DirCtl(1);
- pwm_l=pwm+300;
- pwm_r=pwm_l*1.06666f+35;
- if(pwm_l>6000) pwm_l=6000;
- if(pwm_r>6000) pwm_r=6000;
- TIM_SetCompare1(TIM1,pwm_r);//MOTOB
- TIM_SetCompare4(TIM1,pwm_l);//MOTOA
- }
- }
复制代码 调参数简直是调的心累,不知道学习到更高层次这个pid有没有系统和理论的调试方法。直接上程序吧,收minibalancev3.5控制下车运动。可以动,但是不是特别完美。
把电机的线性化取消了,我准备用加速度积分来做,后面的转向可能会改成目标角度,现在用的是叠加pwm。
调试过程中一不小心把亚克力板摔坏了。。。。。。。。。。对了,主控的程序结构改了一下,我发现运算的时间其实只有一点几毫秒,什么串口和oled之类的会花大量时间,所以我把定时又改成5ms了,然后放在中断服务函数里面。原来有一些担心是多余的。嘿嘿嘿
|
|