当前位置: 首页 > news >正文

2024电赛H题参考方案(+视频演示+核心控制代码)——自动行使小车

目录

一、题目要求

二、参考资源获取

三、参考方案

1、环境搭建及工程移植

2、相关模块的移植 

4、整体控制方案+视频演示

5、视频演示部分核心代码

总结

一、题目要求

         小编自认为:此次H题属于控制类题目,相较于往年较为简单,功能也算单一,四个题目的时间要求都不是很高,容易得分,其中主要难点可能是TI芯片了,但是资源丰富,那也就不是问题了。

二、参考资源获取

        嘉立创官方为了助力电赛,特地推广了一款TI的开发板——MSP0系列刚好是题目要求的),其中覆盖开发环境的搭建(直接最熟悉的用Keil进行开发,同时搭配图形化配置,简直就是Keil+STM32Cube的开发模式),同时配套各种外设的开发教程以及各类传感器等模块的开发教程,附加源码示例,直接移植即可。

嘉立创电赛开发板x2icon-default.png?t=N7T8https://lceda001.feishu.cn/wiki/JNu0wa35pi4feikXbmlcJRwLnGl

 MSPM0G3507开发板icon-default.png?t=N7T8https://wiki.lckfb.com/zh-hans/dmx/

三、参考方案

1、环境搭建及工程移植

        参考立创平台,搭建开发平台,使用Keil进行开发:

环境配置流程icon-default.png?t=N7T8https://wiki.lckfb.com/zh-hans/dmx/beginner/install.html

         重点是:在Keil环境下安装SysConfig 工具。SysConfig 是一个直观而全面的图形实用程序集合,用于配置引脚、外设、子系统和其他组件。它可助我们直观地管理、发现和解决配置冲突,以便有更多时间去编写核心逻辑代码。如下,其配置界面:

2、相关模块的移植 

 1、移植MPU6050模块

        该模块主要用来转向角度控制等,可以使小车走直,平稳角度转向等。

 2、移植TB6612电机驱动模块

        用以驱动电机。

 控制电机时,最好加上速度环控制,所以需要对编码器进行测速,可以通过配置定时器和外部中断实现测速,可以参考esp32测速方式。

参考内容:编码器相关知识及ESP32-Arduino程序_esp32解算ab编码器-CSDN博客

其他模块根据需要自行移植。。。。。。

4、整体控制方案+视频演示

        这里只是为了验证方案,采用的是STM32为主控,OpenMV摄像头巡线,但控制方案、巡线原理都一样,都是通过控制黑线与中心线的偏差关系,只是电赛官方要求不准用摄像头,但用灰度传感器也一样。通过灰度传感来获取偏差,灰度优点是点位准确,只是数据相对摄像头获取的较为离散,但只用比列控制,也完全足够了。

        最后根据速度环、转向环、巡线环的控制方式验证一下方案。以速度环为整体控制内环,外环由转向环和巡线环选择作用,在遇到黑线时开启巡线环,脱离黑线时开启转向环,其中转向环主要控制小车转向,并且按照某一方向直线行驶,如果转向不稳定,或者要求更高,可以引入角速度环。

        基本控制流程框图如下:

         方案改进:如果转向不稳,则可以引入角速度环,以控制转向时的速度稳定。。。。。。

以下为相关演示视频(原视频,去原声):

2024电赛H题方案演示一

2024电赛H题方案演示二

        方案基本可行,速度稳定且并未到达该车上限,需要进一步的优化控制逻辑,这里使用的是统一速度行驶,可采取变速行使,可进一步提高稳定性和减少整体耗时。明显缺陷:MPU6050存在零漂等,准确度不好,如能用算法解决,稳定性可进一步提高,其次该车的初始摆放位置较为重要, 初始角度为后续转向的参考。若采用四轮小车,只需将左边两轮和右边两轮进行分别同步即可,可能还需要微调参数。

5、视频演示部分核心代码

#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;//cmif(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);}
}

        其中,代码较为粗糙,可以进一步改善:

1、交叉走圈时,可以先转到指定角度,然后再加基础速度,稳定性可能要好的多,方便提速。

2、再经过ABCD点一定距离或时间时,可以加快速,快到ABCD点时或到ABCD点时减速,甚至去掉基础速度,整体采用变速运行,前提是巡线和直线行驶部分要稳。

3、MPU6050零漂处理,有条件直接换更好的陀螺仪使用,如果要继续使用,可以采用:

        (1)在小车运行前,要等待其初始化完成,并稳定读取初始值,然后再启动小车的运动控制。

        (2)更好的是,等待其初始化完成后,多次进行数据读取并采用均值滤波,将处理后的值作为初始值,最后再进行小车运动控制。

4、等待大家发言,有更好方法欢迎评论留言。


总结

        控制的难点就在与ABCD四点之间的丝滑连接,如何让小车又快又稳的运行,最后比拼的就是时间了,可能也是比赛现场的重点评判标准,毕竟选择该题的人多

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 函数式编程范式
  • go-kratos 学习笔记(6) 数据库gorm使用
  • 后端返回列表中包含图片id,如何将列表中的图片id转化成url
  • vue3 命令运行窗口暴露网络地址,以及修改端口号
  • AI技术革命对未来就业的影响
  • GUI图形化界面操作(下部)
  • 基于Java的微博传播分析系统的设计与实现
  • 设计模式实战:任务调度系统的设计与实现
  • Vue2从基础到实战(v-bind对于样式控制的增强-操作style)
  • Python 和 Boto3 生成 Amazon S3 对象的 HTTPS URL
  • 2025第十九届中国欧亚国际军民两用技术及西安国防电子航空航天暨无人机展
  • UE5.4内容示例(3)FBX_Import_Options - 学习笔记
  • postMessage 收到消息类型 “webpackWarnings“
  • C#实现数据采集系统-modbustcp数据通知
  • 云服务器部署vite前端项目
  • 时间复杂度分析经典问题——最大子序列和
  • CoolViewPager:即刻刷新,自定义边缘效果颜色,双向自动循环,内置垂直切换效果,想要的都在这里...
  • electron原来这么简单----打包你的react、VUE桌面应用程序
  • NLPIR语义挖掘平台推动行业大数据应用服务
  • Python学习之路13-记分
  • Spring思维导图,让Spring不再难懂(mvc篇)
  • Zepto.js源码学习之二
  • 基于HAProxy的高性能缓存服务器nuster
  • 快速体验 Sentinel 集群限流功能,只需简单几步
  • 前端每日实战 2018 年 7 月份项目汇总(共 29 个项目)
  • 如何胜任知名企业的商业数据分析师?
  • PostgreSQL之连接数修改
  • 函数计算新功能-----支持C#函数
  • 继 XDL 之后,阿里妈妈开源大规模分布式图表征学习框架 Euler ...
  • #laravel部署安装报错loadFactoriesFrom是undefined method #
  • #我与Java虚拟机的故事#连载14:挑战高薪面试必看
  • $().each和$.each的区别
  • (4)事件处理——(6)给.ready()回调函数传递一个参数(Passing an argument to the .ready() callback)...
  • (C语言)球球大作战
  • (vue)页面文件上传获取:action地址
  • (二)hibernate配置管理
  • (附源码)ssm高校升本考试管理系统 毕业设计 201631
  • (附源码)小程序儿童艺术培训机构教育管理小程序 毕业设计 201740
  • (黑马点评)二、短信登录功能实现
  • (简单有案例)前端实现主题切换、动态换肤的两种简单方式
  • (七)Knockout 创建自定义绑定
  • (五)关系数据库标准语言SQL
  • (原创)boost.property_tree解析xml的帮助类以及中文解析问题的解决
  • (正则)提取页面里的img标签
  • (转)linux自定义开机启动服务和chkconfig使用方法
  • .bat批处理(二):%0 %1——给批处理脚本传递参数
  • .bat批处理(一):@echo off
  • .NET Remoting学习笔记(三)信道
  • .NET+WPF 桌面快速启动工具 GeekDesk
  • .net图片验证码生成、点击刷新及验证输入是否正确
  • .one4-V-XXXXXXXX勒索病毒数据怎么处理|数据解密恢复
  • @Transactional注解下,循环取序列的值,但得到的值都相同的问题
  • []T 还是 []*T, 这是一个问题
  • [AI Embedchain] 开始使用 - 全栈
  • [AIGC] Java 和 Kotlin 的区别