2022电赛小车跟随行驶系统(C题)复盘
此次的电赛感觉结束的挺突然的,在找到方向准备细化地进行调试的时候却是没有足够时间来完成代码上的完善。想着此次遗憾,写一篇博客来记录一下自己的经历吧,总结总结此次的电赛时光。
首先便是题目的选择,由于我们之前校电赛时简单接触过小车的题目,在简单看了一下这几个题目后,还是选择了C题小车。
简单分析一下题目有以下几点要求:
- 限定采用TI的MCU,速度0.3~1m/s
- 每完成一次行驶(即完整完成一项任务)到终点时小车要发出声音提示。
- 当行驶在内圈BFD段时,小车要发出灯光指示。
- 停车时车距20cm(误差6cm)
赛道如图所示,详细任务要求在代码处分析
整体流程记录:
在定下选题之后,我们首先要做的便是搭一个车架子出来。根据我们准备的材料我们采用了亚克力板来切割打孔并作为我们的车架。题目要求的长宽分别不超过25cm和15cm,我们便把亚克力板裁成10*20cm的大小后在上面打孔安装。
供电电路的焊接和车子的安装还是花了我们不少的时间,大概在第二天上午基本完成,且暂时缺少电机,于是用的两个万向轮和两个减速电机在初步调试。(现在拼出的车甚至可以丝滑地漂移,着实有点好van)
这之后我们开始先试着用32来调试,在网上搜到了一个用编码器控制电机例程,下下来修修改改,之后想着用AB相采到的脉冲数来计算距离速度(输入捕获法)。
dis += Read_Encoder(3)*0.25*2*3.14*3.5*0.05*0.076;//距离计算
这公式放在定时器1的中断里,每一次进中断它便会计算增加当前走过的距离。没记错的话Read_Encoder(3)为使用定时器3采集到的脉冲数,0.25为的4倍频,2*π*3.5为轮子周长,0.05为衰减比,0.076为每一个脉冲所走的距离。
距离32测试出来和实际的差不多,可惜我们在实际在430上尝试时误差感觉过大也不稳,没找到问题所在最后放弃了编码器测距。第二天白天晚上的时间就整了32的编码器测距以及430的串口上面的调试同步进行的还有超声波模块的移植。
在第三天白天到来的时候,除了串口我们其他的都已失败,这时遭不住赶紧回去再浅睡一下,直到我们的电机到来,开始把咱们的车子都换成四轮车再重理一下逻辑,调合适的速度。下午近晚上的时候,我们超声波移植失败,但另一个兄弟写了了一个出来。这时我们发现最为重要的两车通信还没整出来。于是开始了艰难地调试。
在晚上两点左右整出通信的时候,我们又遇到了新的问题!!!小车巡线寻不准要巡出去,车轮打滑?!后来轮子换来换去,整了个小轮子再给轮子缠了几圈胶才算整完。而巡线在观察其症状和好几遍的代码复查后,我们抱着怀疑的态度然后换了连接灰度模块的杜邦线,啪的一下很快蛤,他就能正常巡线了。。。于是时间来到了第四天早上七点左右,整个人状态也不是很得行。最后在一个白天的持续代码调整下结束了最后一天。遗憾的是在我们赛道上只实现了1、2、4要求,且代码优化上仍未做好,应是遗留了一些小bug,最后也是遗憾收场。
时间过的很快,我们有过错误的尝试,浪费了不少时间,若是时间运用好也许就能优化好代码了。长个经验吧。。。
一、整体要求计算及分析
内圈周长:C =2πr+2l+2w=2*3.14*0.3+2*0.9+2*0.6 = 4.884 m
外圈周长:C =2πr+2l+2w =2*3.14*0.3+2*1.2+2*0.6 = 5.484 m
要求1: 都沿着外圈行驶,领头小车放在路径的起始位置A点,跟随小车放在其后20cm处,领头小车的速度为0.3m/s,平均速度误差不大于10%,速度范围0.27m/s~0.33m/s,小车循迹一圈时间范围:16.62s~20.31s
要求2: 都沿着外圈行驶,领头小车放在路径的起始位置A点,跟随小车放在E边上,领头小车的速度为0.5m/s,平均速度误差不大于10%,速度范围0.45m/s~0.55m/s,小车循迹一圈时间范围:9.97s~12.18s
要求3:将领头小车放在路径的起始位置A点,跟随小车放在其后20cm处,领头小车和跟随小车连续完成三圈路径的行驶。第一圈领头小车和跟随小车都沿着外圈路径行驶。第二圈领头小车沿着外圈路径行驶,跟随小车沿着内圈路径行驶,实现超车领跑。第三圈跟随小车沿着外圈路径行驶,领头小车沿着内圈路径行驶,实现反超和再次领跑。速度最低0.3m/s
要求4:都沿着外圈行驶,领头小车放在路径的起始位置A点领头小车的速度为1m/s,平均速度误差不大于10%,速度范围0.9m/s~1.1m/s,小车循迹一圈时间范围:4.985s~6.093s,等停标志处停5s后继续向前行驶,达终点后停下。
在看完这四个要求后,首先想到的是整体分成四个模式,正好MSP430F5529的板子上刚好有两个按钮,一个来切换模式,另一个来控制小车启动。
主机整体的逻辑判断建立在按钮上,其代码如下:
if(KEY_isPressed(KEY2))//按钮2{DELAY_MS(100);// 消抖if(KEY_isPressed(KEY2)){int i_num=0;//长按计数while(KEY_isPressed(KEY2)){DELAY_MS(100);i_num++;}if(i_num>20)//长按超过两秒进入设置模式{int set_out=1;//设置模式标志位OLED_PrintfAt(FONT_ASCII_6X8,0,6,"MODE%d SET ",key_statues);//显示进入设置模式while(set_out){OLED_PrintfAt(FONT_ASCII_6X8,1,6,"forward%d",mode_forward[key_statues]);//显示当前设置的前进速度if(KEY_isPressed(KEY1)){DELAY_MS(320);if(KEY_isPressed(KEY1)){ mode_forward[key_statues]=mode_forward[key_statues]+5;//按钮1按一次+0.5%占空比}}if(KEY_isPressed(KEY2)){DELAY_MS(320);if(KEY_isPressed(KEY2)){int j_num=0;while(KEY_isPressed(KEY2)){DELAY_MS(100);j_num++;}if(j_num>20){set_out=0;//长按2s退出设置模式}else{ mode_forward[key_statues]=mode_forward[key_statues]-5;//按钮2按一次-0.5%占空比j_num=0;}}}}i_num=0;DELAY_MS(100);}else//短按切换运行模式一共4个{i_num=0;LED_Turn(LED1); key_statues++;if(key_statues>4){key_statues=0;}}}}if(KEY_isPressed(KEY1))//按键1 触发启动{DELAY_MS(320);if(KEY_isPressed(KEY1)){LED_Turn(LED1); key_start++;mode_2_num=1;mode_4_num=1;mode_3_num=2;UART_Printf (UART1,"AT+CIPSEND=0,4\n");DELAY_MS(3);UART_Printf(UART1,"$%d\n",key_statues);//WIFI模块发送给从机模式以及启动信号if(key_start>1){key_start=0;}}}if(key_start)//判断是否按下启动按钮{switch(key_statues)//选择执行对应模式{case 0: no_mode();break;case 1: MODE_1();break;case 2: MODE_2();break;case 3: MODE_3();break;case 4: MODE_4();break;}}
二、巡线逻辑
首先是我们的5路灰度模块,用的中间3个比较近的在巡线,外面两个用来补救或判断,本次没有在此文档中完善。
本次巡线需注意这里的岔路分支点,我们由于灰度模块的宽度合适,可以刚好识别出让灰度模块识别出101(黑线返回为1空白返回为0),此处加个延时右转或左转即可稳定走外圈内圈。但是当小车从D点处回来时还是略有不稳,外圈没问题,但内圈有概率误判为终点
巡线部分逻辑代码如下:
//读取灰度模块的返回值
int read_sensor_values()
{sensor[0] = GPIO_ReadBit(P4,1); //左 扫到为1sensor[1] = GPIO_ReadBit(P4,2); //中sensor[2] = GPIO_ReadBit(P2,7); //右if ((sensor[0] == 1) && (sensor[1] == 1) && (sensor[2] == 1)) {if(mode_2_num){mode_2_num=0;error = 0;DELAY_MS(300);}else if(mode_4_num){_stop_hard(500);UART_Printf (UART1,"AT+CIPSEND=0,4\n");DELAY_MS(3);UART_Printf(UART1,"$6\n");//发送暂挺信号让后车与主车一同停止5s后继续完成路程_stop();DELAY_MS(4000);mode_4_num=0;forward(1000);DELAY_MS(200);}else{error = 3;}// 1 1 1 停} else if ((sensor[0] == 0) && (sensor[1] == 0) && (sensor[2] == 1)){error = 2;// 0 0 1 右转} else if ((sensor[0] == 0) && (sensor[1] == 1) && (sensor[2] == 0)) {error = 0;// 0 1 0 直行} else if ((sensor[0] == 1) && (sensor[1] == 0) && (sensor[2] == 0)) {error = 1;// 1 0 0 左转} else if ((sensor[0] == 1) && (sensor[1] == 0) && (sensor[2] == 1)) {error = 2;// 1 0 1 右转,主要用在寻到岔路时右转回正}
// else if ((sensor[0] == 1) && (sensor[1] == 1) && (sensor[2] == 0))
// {
// error = 1;// 1 1 0 左转
// } return error;}
三、超声波模块
触发信号Tirig维持10Us以上的高电平即可等待Echo的返回,这里是用EXTI检测跳变信号,去打开和关闭定时器,最后一次测量计算结果后清除定时器计时,并等待下一个循环开始。
以上时序图表明你只需要提供一个10uS 以上脉冲触发信号,该模块内部将发出8个40kHz周期电平并检测回波。一旦检测到有回波信号则输出回响信号。回响信号的脉冲宽度与所测的距离成正比。
距离=高电平时间*声速(340M/S)/2
主要代码如下:
void HCSR04_TRIG_Send(void)//超声波模块触发测距
{
GPIO_SetBits (PORT6, GPIO_Pin_0);
delay_us(20); //延时20US(至少延时10us)
GPIO_ResetBits (PORT6, GPIO_Pin_0);
}//定时器中断触发
__interrupt void TIMER_A1_IRQ_Handler()
{ static uint16_t start_value = 0,stop_value = 0;
// LED_Turn(LED1); //指示灯闪烁if(TIMER_GetITStatus(TIMER_A1,TIMER_CCR1_IRQn)) //获取某一通道中断标志{//如果捕获到上升沿if(TIMER_GetChannelPinInValue(TIMER_A1,TIMER_CH1) == BIT_SET){start_value = TIMER_Capture_GetValue (TIMER_A1,TIMER_CH1); //读取发生该捕获条件时的计数值overflowTime = 0;}//如果捕获到下降沿else {stop_value = TIMER_Capture_GetValue (TIMER_A1,TIMER_CH1); //读取发生该捕获条件时的计数值PulseWidth = TIMER_Capture_CalTime_Us(start_value,stop_value,overflowTime);//读取捕获时间并转化为距离distance = PulseWidth/2 * 340.0 /1000000;//读取捕获时间并转化为距离;单位为mdistance =distance*100;//单位cmTIMER_Capture_Clear (TIMER_A1,TIMER_CH1); //清零overflowTime = 0;}TIMER_ClearITPendingBit(TIMER_A1,TIMER_CCR1_IRQn); //清除TIMER的某一个中断标志}if(TIMER_GetITStatus(TIMER_A1,TIMER_OverFlow_IRQn))//如果溢出{overflowTime++; //溢出值加1TIMER_ClearITPendingBit(TIMER_A1,TIMER_OverFlow_IRQn); //清除TIMER的某一个中断标志}TIMER_ClearITPendingBit(TIMER_A1,TIMER_OverFlow_IRQn); //清除TIMER的某一个中断标志}
四、两车通信
小车间使用的ESP32-C3进行通信,用串口配置好模块后就可以使用串口来进行两车间的通信了,要保证主机先上电开启热点,从机再上电连上主机WiFi模块,之后便可以通过串口来进行通信一起启动停止了。相关代码查模块对应的指令应该就行了。
五、完赛总结
封箱的时候想着我们这个拼拼凑凑的小车完成3个任务还是没问题的,也没想到最后只有第一个完美完成,其他要求后车都出了点问题,逻辑仍有一些bug(我们自己的赛道上没有,换了赛道之后就显现出来了)。没有用PID调速,用的定的PWM来确定速度也让我们的车不是十分丝滑,手动按钮调速增加了一些容错率。转弯速度定死了的,让我们只有在0.3m/s时比较丝滑。
可惜没出来就是没出来,就当一次很好的锻炼吧,在看了其他参赛小组的方案和小车的运行效果后,我也想到了一些继续优化我们自己小车逻辑的方向和方案。如要求2,我们不断在根据超声波模块测得的距离加速减速,其效果不是很好,容易撞车且后车也容易被甩远。我们可以先后车开机启动即高速定死,追上至一定距离后直接调速至前车速度相近的pwm值并不断微调,也许这样比一开始直接开始调速要好。
本次的电赛结束了,有遗憾也有收获,认识到了自己的不足,也见识到了大佬的厉害,开阔了自己眼界。希望此次的经历化作未来的能力,简单记录一下这一同度过的特殊时光吧。望一起努力的小伙伴们共回忆(那天晚上墨客的汉堡是正的香!)。
---------------------------------------------------------------------------------------------------------------------------------
IOTAT——2022/8/3
2022电赛小车跟随行驶系统(C题)复盘相关推荐
- 广西大学电赛 C题-小车跟随行驶系统-系统方案设计
广西大学电赛 C题-小车跟随行驶系统-系统方案设计 1. 题目 今天看看电赛题,个人觉得C题比较容易,其他题目对于学生来说比较复杂不好拿奖 先看看题目要求: 分析实现: 1)内圈外圈等停标志,线识别 ...
- 2022电赛C题:小车跟踪(方案1+核心代码)
目录 前言 一.题目 二.方案1 1.材料清单 2.说明 三.核心代码 四.工程获取 前言 针对2022年电赛C题小车跟踪,本团队一共是做了两种方案: 第一种主要以摄像头(openmv)为 ...
- 2022电赛F题思路
2022电赛到现在为止已经出了结果.这是我第一次参加电赛,以前也没有相关的比赛经历,在这四天三夜的时间里能够和队友完成这样一项完整的作品,对我们来说都具有很大的意义.虽然最后还是有一些细节上的问题,不 ...
- MSP430F5529LP 2022电赛学习准备及相关例程
写在前面: 写下这篇东西的目的首先是希望自己以后忘记MSP430如何使用的时候,能够在看到这篇记录之后能够迅速想起.其次,也希望能够为其他同学或者有需要的人提供一点帮助,话不多说,下面开始正文. 目录 ...
- 2022电赛声源定位(基础篇)
对于需要2022电赛题目的同学点击这个链接:https://pan.baidu.com/s/1zyC8MbgenAAQ_ZVmvFyZvg 提取码:g6kd 对于这个2022电赛E题声源定位的音频点击 ...
- 2022电赛省一-小车跟随行驶系统(C题)
⏩ 大家好哇!我是小光,嵌入式爱好者,一个想要成为系统架构师的大二学生. ⏩前段时间参加了电赛的校赛.七校联赛和省赛,校赛和七校联赛都获得了三等奖,省赛上也是获得了一等奖的好成绩
- 通过FPGA实现2022电赛F题
这是本人第一次参加电赛,非常有收获,虽然电赛已经结束,不过并不影响把我的思路整理出来和大家交流一下,同时也为自己做个笔记,这里简单介绍一下思路,就不讲解程序了. 这次电赛的题目如下: 1. 设计思路 ...
- 2022 电赛陕西省赛
一:题目: 声源定位跟踪系统(E题) 设计制作一个声源定位跟踪系统,能够实时显示及指示声源的位置,当声源移动时能够用激光笔动态跟踪声源. 设计并制作声音发生装置--"声源",装置最 ...
- 电赛小车常用硬件解析(蓝牙遥控,循迹)
智能小车硬件解析 (蓝牙遥控.循迹)智能小车硬件解析 智能小车硬件解析 前言 一.单片机 1.什么是单片机 2.STM32F103C8T6 3.小车项目总览 4.器材清单 二.电机 1.直流减速电机 ...
最新文章
- 终极AutoCAD大师班:成为AutoCAD专家
- python装饰器执行顺序_python unittest单元测试框架-3用例执行顺序、多级目录、装饰器、fixtures...
- 运维用python可以来做什么_学习Python一般可以用来干什么?
- 深入理解js系列一作用域是什么
- SAP OData请求是如何通过OData Plugin路由到OData Offline Data Store的
- 自动跟随机器人:一种简易的自动跟随方案,自动跟随小车、自动跟随平衡小车、STM32、基于超声波的自动跟随小车
- linux date 常用格式,5、总结Linux常用命令使用格式,并用实例说明。例如echo、screen、date、ifconfig、export等命令...
- LeetCode 1348. 推文计数(哈希map+set)
- 深入理解计算机系统 相关课程,深入理解计算机系统
- python文件命名 数字_在python中,如何导入文件名以数字开头
- 杭州电子科技大学acm--2006
- python实现KNN分类算法(鸢尾花数据集)
- Python打包为exe文件
- 导弹气动估算matlab,基于Fluent的导弹气动特性计算
- 两年数据对比柱形图_同期数据对比,你会做这样特殊的柱形图吗?趋势、差异值一目了然...
- MATLAB实现自编码器(三)——堆栈自编码器Stacked Autoencoders实现手写数字分类
- 怎样用Excel搜索表格内的内容?
- R语言使用glmnet包拟合lasso-cox回归模型(包含生存时间和结果标签)、使用lasso-cox模型进行特征筛选、使用sapply函数对特征数据进行标准化z-score
- 将数字字符串转换为人民币大写,壹、贰、叁、肆、伍、陆、柒、捌、玖、拾
- PCA参数,属性,接口列表
热门文章
- IDCC2018|格力电器数据中心首席研发工程师 李宏波:格力永磁变频冷水机组打造绿色节能IDC...
- poj1734 Sightseeing trip[最小环]
- 从指定文件夹下很多个excel中读取指定内容,并合并成一个表,再增加字段
- 使用谷歌浏览器扩展查排名(开发谷歌浏览器扩展)
- 循环定时器HMI(宏指令)实现(附源代码)
- 【贪吃蛇小游戏】宝塔面板快速搭建贪吃蛇小游戏Web网站 - 无需云服务器
- No suitable driver found for jdbc:mysql://localhost:3306/shumei?serverTimezone=UTCuseSSL=NO
- Web前端—既可以输入又可以选择的input框
- DGUS屏如何实现超大点阵字库显示?
- 软考必过 - 系统架构师 - 系统架构设计