一:题目要求:
个人认为:拿到题目时,赛题的主要难点有两点:
1:使用的芯片并不是大家常用的32作为主控,题目明确要求使用Ti的MSPM0芯片,在网上找到的主要有两个(M0L1306和M0G3507)两款芯片的差异还是挺大的,做开始配环境的时候使用的是M0L1306但是会出现各种各样的bug,后来换了M0G3507之后外设之间的工作就正常了所以最后是选用了M0G3507作为主控
2:就是各个PID环之间的切换,我们使用了速度环,角度换作为两个主要的环,具体的使用思路会在下文做介绍,A,B,C,D每个位置的PID要相互结合才能较好地实现功能。
二:硬件设计:
这里首先要感谢B站的up主:御龙老大哥,在赛前的时候实验室的同学在网上看到了大哥的项目,并将此项目的资料收入囊中,对此次的电赛帮助很大,大哥的项目是完成了小车的速度环,距离环,循迹环,角度环,角速度环的封装,包括上位机和使用按键进行OLED菜单的切换,硬件上也有嘉立创的原理图与PCB,相当于此项目已经把要用底层算法封装完成,要做的就是将他们组合起来进行联调即可(这个过程还是挺痛苦的),如果想要了解复刻的友友可以去B站支持一下。
三:软件配置:
1.环境配置
常说点亮了一个LED就是成功了一半了,开发环境是在赛前的时候配置的,使用的是(Keil+sysconfig)的方法,具体的配置就不再一一介绍了,有相应的教程,要注意的就是Keil的版本不能太低,另外就是改文件路径的时候对应的文件名要修改正确否则在Keil里面是无法跳转的。
2.sysconfig使用:
对于Ti推出的初始化配置软件来说肯定是没有Cubemx好用的,最起码他没有帮你像Cubemx那样帮你把工程配置好,再加上Ti官方提供的历程模板也不是那么好用,所以电赛时使用的就是大哥的资料,在资料里面的空白例程里做了一些移植(OLED,MPU6050,编码器计次),后面由于时间原因并没有移植。
使用他的主要注意点就是配置完相应的IO口之后并不会生成工程,而是要使用三个文件:
要把这三个文件导入到使用的工程里面,这样才可以把配置好的设置同步到工程里面,IO口才可以初始化完成。对于里面的详细配置如果有兴趣可以稍微整理一下,具体的太多了就不一一介绍了。
3.整体配置:
(1)编码器配置:
由于M03507的定时器支持使用编码器的模式只有一个定时器(真的难绷了,F103都有三个定时器支持编码器输入),所以这个方案就没办法了,后面就是用的外部中断读取高低电平进行编码器的计次了,具体的实现逻辑与STM32的方法一致。
(2)OLED使用的是软件IIC进行的,MPU6050使用硬件IIC(使用软件IIC没有成功,好像是因为GPIO口的速率太慢了,所以就放弃了),定时器输出PWM波,这些就和平时使用32做小车的配置很相似了。
四:整体逻辑:
任务一:使用速度环进行,小车执行任务一的时候两个轮子就走速度环走相同的速度就可以走直线,检测到黑线之后可以使用电机失能和速度环置零的方法,实测下来差的不是很多,使用速度环置零的方法停下来的速度更快,要注意速度不建议给的非常大,虽说跑得是快了,但是单片机输出PWM有先后所以其实没法做到真正意义上的同步。
任务二:从A到B走速度环直接到达(同任务一),走到B点循迹到黑线以后就走循迹环到C点,在C点进行一个角度矫正,矫正之后走速度环+角度环,保证小车可以走直线到达D点,在D点走入循迹之后到A点没有检测到循迹就停下来。
任务三:开机后等待MPU6050角度解算完成,之后使用角度环达到相应角度(35~40度范围),走速度环+角度环到达C点后走循迹到达B点,在B点没有循迹到白线的时候就使用角度环进行第二次角度矫正(角度范围:180~190),矫正后走速度环+角度环到D点后,走循迹到达A点没有检测到黑线就停下来。
任务四:虽说看着任务四是任务三走四圈,但是使用MPU6050的时候发现其零飘与温漂的情况比较严重,比赛时换用精度更高的传感器显然也来不及(如果有精度更高的传感器,这个题应该是可以秒了的!)所以对于参数的调整就至关重要了,每一圈走下来MPU6050的飘逸有一定范围但是基本上是在一个区间内(我们实测大概是-10~-20之间)所以每一圈需要转的参数可以定下来的,需要改的只是角度范围,大体的逻辑并没有怎么改变的。
五:具体实现细节:
1.速度环+角度环
上面的思路里面大多都是一个PID闭环就可以实现,但是有一个速度环+角度环的有点说法,起初,我们使用速度环的时候发现第二问从C点出来的时候没办法让他车头刚刚好走直线的那个方向,需要有一个角度校验的意思,而且并不能保证可以正正好走到D点的黑线端(要么偏外,要么偏里)。
所以在C点出来之后加一个角度环就比较关键了,这时可能会想为什么不用PID串联呢(四天三夜的时间确实吧有点赶,后面还有参数需要标定所以没采用),所以我们在1ms的定时器里面定义了两个static变量,两个变量分别自增到相应的数值以后执行速度环或者角度环,因为时间切换的比较快,在宏观上是感觉两个环同时工作的,就实现两个环的叠加,具体实现代码如下:
static uint8_t Angle_Start = 0;
static uint8_t Speed_Start = 0;
if(Angle_Speed_Flag == 1)
{
Speed_Start++;Angle_Start++;
if(Speed_Start >= 10) //速度环
{
//开启速度环
Speed_Start = 0;
}
if(Angle_Start >= 20) //角度环
{
//开启角度环
Angle_Start = 0;
}
}
就是让两个环不断地切换达到一起运行的效果,最终实现的效果还是不错的, 除了会导致速度降低(但不会降低很多,暂时还没有想明白因为什么)。最终应用到后面三问的效果还是不错的。
2.任务切换
MPU6050的漂移问题在这个题目中的影响就非常严重了,特别是在回到原点的时候我们发现他会出现自增的状态,复位之后可能其内部并没有处于原位,再去跑下一问的时候就会出现问题,所以最后我们打算使用重新上电的方法来解决,但是重新上电的时候任务切换有点难,所以我们设计了两个IO口通过读取IO口的电平状态来切换任务,具体逻辑与代码实现如下:
//Read_State2与Read_State1是读取IO电平状态
uint8_t taskstate(void){
uint8_t State;
State = (Read_State2<<1) | (Read_State1) ;
return State;
}
if(taskselect==0)
{
task1();
}
if(taskselect==1)
{
task2();
}
if(taskselect==2)
{
task3();
}
if(taskselect==3)
{
task4();
}
通过上电的时候读取电平选择任务实现的效果可以消除一部分的MPU6050的漂移。
后面的一些心得会慢慢整理出来