目录
一、题目要求
小编自认为:此次控制类类型题目的H题,相较于往年较为简单,功能也算单一,四个题目的时间要求都不是很高,容易得分,其中主要难点可能是TI芯片了,但是资源丰富,那也就不是问题了。
二、参考资源获取
嘉立创官方为了助力电赛,特地推广了一款TI的开发板——MSP0系列(刚好是题目要求的),其中覆盖开发环境的搭建(直接最熟悉的用Keil进行开发,同时搭配图形化配置,简直就是Keil+STM32Cube的开发模式),同时配套各种外设的开发教程以及各类传感器等模块的开发教程,附加源码示例,直接移植即可。
嘉立创电赛开发板x2https://lceda001.feishu.cn/wiki/JNu0wa35pi4feikXbmlcJRwLnGl
MSPM0G3507开发板https://wiki.lckfb.com/zh-hans/dmx/
三、TI板子可能用到的资源
1、环境搭建及工程移植
参考立创平台,搭建开发平台,使用Keil进行开发:
环境配置流程https://wiki.lckfb.com/zh-hans/dmx/beginner/install.html
重点是:在Keil环境下安装SysConfig 工具。SysConfig 是一个直观而全面的图形实用程序集合,用于配置引脚、外设、子系统和其他组件。它可助我们直观地管理、发现和解决配置冲突,以便有更多时间去编写核心逻辑代码。如下,其配置界面:
2、相关模块的移植
1、移植MPU6050模块
该模块主要用来转向角度控制等,可以使小车走直,平稳角度转向等。
2、移植TB6612电机驱动模块
用以驱动电机。
控制电机时,最好加上速度环控制,所以需要对编码器进行测速,可以通过配置定时器和外部中断实现测速,可以参考esp32测速方式。
参考内容:编码器相关知识及ESP32-Arduino程序_esp32解算ab编码器-CSDN博客
其他模块根据需要自行移植。。。。。。
四、控制参考方案
1、整体控制方案+视频演示
这里只是为了验证控制方案,小编没有电赛器材,所以就以STM32为主控,OpenMV摄像头巡线的方案进行演示。但控制方案、巡线原理都一样,都是通过控制黑线与中心线的偏差关系,只是电赛官方要求不准用摄像头,但用灰度传感器也一样。通过灰度传感来获取偏差,灰度优点是点位准确,只是数据相对摄像头获取的较为离散,但只用比列控制,也完全足够了。
根据速度环、转向环、巡线环的控制方式验证一下方案。以速度环为整体控制内环,外环由转向环和巡线环选择作用,在遇到黑线时开启巡线环,脱离黑线时开启转向环,其中转向环主要控制小车转向,并且按照某一方向直线行驶,如果转向不稳定,或者要求更高,可以引入角速度环。
基本控制流程框图如下:
方案改进:如果转向不稳,则可以引入角速度环,以控制转向时的速度稳定。。。。。。
以下为相关演示视频(原视频,关闭原声):
2024电赛H题方案演示一
2024电赛H题方案演示二
方案基本可行,速度稳定且并未到达该车上限,需要进一步的优化控制逻辑,这里使用的是统一速度行驶,可采取变速行使,可进一步提高稳定性和减少整体耗时。明显缺陷:MPU6050存在零漂等,准确度不好,如能用算法解决,稳定性可进一步提高,其次该车的初始摆放位置较为重要, 初始角度为后续转向的参考。若采用四轮小车,只需将左边两轮和右边两轮进行分别同步即可,可能还需要微调参数。
2、视频演示部分核心代码
-
#define limit_180_Z(n) ((n>0)?(n-360):n)
-
#define limit_180_F(n) ((n<0)?(n+360):n)
-
-
int base_speed =
70;
// cm/s
-
int Target_angle =
0;
-
-
#define OpenMV_Kp 1.1
-
#define Line_Kp 2
-
uint8_t ABCD_flag =
0;
-
uint8_t TI_flag =
2;
-
-
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
-
{
-
float angle_Err =
0;
-
static
uint8_t last_line_flag =
0;
-
if(htim->Instance == TIM2 )
-
{
-
motorA.speed =
get_speed_motorA();
-
motorB.speed =
get_speed_motorB();
-
// motorA.S += motorA.speed*0.01;//路程等于速度积分,单位:cm
-
// motorB.S += motorB.speed*0.01;//cm
-
-
-
if(last_line_flag != line_flag)
-
{
-
ABCD_flag++;
-
}
-
last_line_flag = line_flag;
-
if(line_flag ==
1)
//巡线
-
{
-
motorA.Target_Speed = base_speed - rho_org * OpenMV_Kp;
-
motorB.Target_Speed = base_speed + rho_org * OpenMV_Kp;
-
}
-
else
//转向和直线行使
-
{
-
if(TI_flag ==
1)
//视频一演示,不交叉走圈
-
{
-
if(ABCD_flag ==
2||ABCD_flag ==
6||ABCD_flag ==
10||ABCD_flag ==
14)
-
{
-
Target_angle =
-180;
-
angle_Err =
limit_180_Z(MPU6050.yaw)-(Target_angle+ABCD_flag*
0.6);
-
}
-
else
-
{
-
Target_angle =
0;
-
angle_Err = MPU6050.yaw-(Target_angle+ABCD_flag*
0.5);
-
}
-
-
}
-
else
if(TI_flag ==
2)
//视频二演示,交叉走圈
-
{
-
if(ABCD_flag ==
0||ABCD_flag ==
4||ABCD_flag ==
8||ABCD_flag ==
12)
-
{
-
Target_angle =
-33;
-
angle_Err = MPU6050.yaw-Target_angle;
-
}
-
-
if(ABCD_flag ==
2||ABCD_flag ==
6||ABCD_flag ==
10||ABCD_flag ==
14)
-
{
-
Target_angle =
215;
-
angle_Err =
limit_180_F(MPU6050.yaw)-Target_angle;
-
}
-
}
-
motorA.Target_Speed = base_speed - angle_Err * Line_Kp;
-
motorB.Target_Speed = base_speed + angle_Err * Line_Kp;
-
if(ABCD_flag ==
16)
//走完四圈停下来
-
{
-
motorA.Target_Speed =
0;
-
motorB.Target_Speed =
0;
-
}
-
}
-
motorA.out =
pid_control(POSITION_PID,motorA.speed,motorA.Target_Speed,
200,
18,
15);
-
motorB.out =
pid_control(POSITION_PID,motorB.speed,motorB.Target_Speed,
200,
18,
15);
-
Load(motorA.out, motorB.out);
-
}
-
}
完整工程请查阅:2024电赛STM32+OpenMV版完整工程(主要展示小车控制方案)https://download.csdn.net/download/qq_67319052/89599871
其中,代码较为粗糙,可以进一步改善:
1、交叉走圈时,可以先转到指定角度,然后再加基础速度,稳定性可能要好的多,方便提速。
2、再经过ABCD点一定距离或时间时,可以加快速,快到ABCD点时或到ABCD点时减速,甚至去掉基础速度,整体采用变速运行,前提是巡线和直线行驶部分要稳。
3、MPU6050零漂处理,有条件直接换更好的陀螺仪使用,如果要继续使用,可以采用:
(1)在小车运行前,要等待其初始化完成,并稳定读取初始值,然后再启动小车的运动控制。
(2)更好的是,等待其初始化完成后,多次进行数据读取并采用均值滤波,将处理后的值作为初始值,最后再进行小车运动控制。
4、等待大家发言,有更好方法欢迎评论留言。
五、总结
控制的难点就在与ABCD四点之间的丝滑连接,如何让小车又快又稳的运行,最后比拼的就是时间了,可能也是比赛现场的重点评判标准,毕竟选择该题的人多,水涨船高。