基于MSP432P401R爬坡小车【2020年电赛C题】

文章目录

  • 一、任务清单
    • 1. 硬件部分
    • 2. 软件部分
  • 二、OpenMV巡线
  • 三、舵机转向
  • 四、停止线识别
  • 五、技术交流


一、任务清单

1. 硬件部分

  • 主控板: MSP432P401R
  • 数据显示: OLED
  • 电机: 霍尔编码器电机
  • 电池: 7.3V航模电池
  • 巡线: OpenMV H7 Plus
  • 警报: 蜂鸣器
  • 电机驱动: TB6612
  • 仪器: 3D打印机
  • 视觉云台: 3D建模打印
  • 转向: 数字舵机
  • 其他: 铜柱、螺丝螺母、开关、面包板等。
    在这里插入图片描述

2. 软件部分

  • 编译器: Keil、OpenMV IDE
  • 建模软件: SketchUp Pro 2022
  • 切片软件: Cura
  • 编程方式: 库函数
  • 编程语言: C、Python

二、OpenMV巡线

这里巡线不用红外探头的原因是考虑到市面上大多红外对该虚线采集的信号并不是很准确,存在偶然因素,故选择摄像头巡线。

这里我通过寻找有效区域内的最大色块,将其x轴坐标返回给单片机,在单片机端进行数据处理,例如摄像头下的分辨率为(w:320,h:240),设感应区域ROI为(0,90,320,60) ,
采集到的有效色块X坐标为162,下图可见,被圈出的大白框矩形为感应区域ROI,中间被圈出的为最大有效色块(图中色块阈值选择为黑色),下方红色圈出的为该色块的X轴坐标。
在这里插入图片描述
获取目标色块:

img = sensor.snapshot()  //截取摄像头的一个图像
blob=img.find_blobs([thresholds[0]], roi=ROI1, x_stride=10, y_stride=5,pixels_threshold=10, area_threshold=10, merge=True)  

筛选出最大色块:

def find_max(blobs):max_size=0for blob in blobs:if blob[2]*blob[3] > max_size:max_blob=blobmax_size = blob[2]*blob[3]return max_blob

输出最大色块X坐标:

x=max_ID.cx()

将有效色块坐标发送至单片机端后该怎样对数据进行处理呢?

  • 方法一:
    例如采集到的坐标为140,可知中心坐标为160,已速度闭环为例,可先将坐标差值Err=140-160=-20,可拟定为负值为偏左,正值为偏右,假如你的闭环在每10ms单相双边沿产生15个脉冲信号,可设定一个线性系数k,有Err/k=P,Err2=Err_Last-Err=I,则Target_L=15+PI,Target_R=15-PI,Target_L和Target_R则为计算后的目标脉冲,具体公式推导这里不做介绍,仅供参考!

  • 方法二:
    这种方法也是更为简单,更为方便的。
    对色块的X坐标进行区域划分,例如中线为160,则:
    ①中心区域可划分为(150,170)
    ②偏左区域可划分为(120,150)、(90,120)、(60,90)、(30,60)、(0,30)
    ③偏右区域可划分为(170,200)、(200,230)、(230,260)、(260,290)、(290,320)
    即可根据不同位置发送不同指令。单片机段根据不同指令执行不同程度的回正操作。

示例如下:


def Send_X(err):if(err>=150 and err<=170):uart.write("F")elif(err>=120 and err<150):uart.write("0")elif(err>=90 and err<120):uart.write("1")elif(err>=60 and err<90):uart.write("2")elif(err>=30 and err<60):uart.write("3")elif(err>=0 and err<30):uart.write("4")elif(err>170 and err<200):uart.write("5")elif(err>=200 and err<230):uart.write("6")elif(err>=230 and err<260):uart.write("7")elif(err>=260 and err<290):uart.write("8")elif(err>=290 and err<320):uart.write("9")

其中Err表示踩到的X坐标,根据不同坐标区域发送不同指令,在单片机端接收操作如下:

	if( openmv_rx=='F' ){}	//偏向左边else if( openmv_rx=='0' ){}else if( openmv_rx=='1' ){}else if( openmv_rx=='2' ){}......//偏向右边else if( openmv_rx=='5' ){}else if( openmv_rx=='6' ){}......

三、舵机转向

舵机转向问题,在学习较为常用的为180°舵机,这里我以180°数字舵机进行简单介绍

常用的舵机大多都分为3根线,其中俩根为VCC和GND,也就是电源线,剩下一根为信号线,也就是控制舵机的线

  • 舵机控制
    关于舵机的控制说的通俗易懂点就是控制信号线的脉宽,通过控制不同脉冲舵机转动不同角度,如下所示:
                20ms为例0.5ms ------------ 0度;1.0ms ------------ 45度;1.5ms ------------ 90度;2.0ms ------------ 135度;2.5ms ------------ 180度;

设一个PWM周期为20ms,则控制有效电平为0.5ms,也就是一百分之一的时候,舵机保持0°,依次类推。

  • 实时转向
    可根据上面巡线返回的信号进行转向,如当接收到信号F时,表示在中心区域,则舵机保持直线行驶状态,也就是90°,若接收到1-4信号,则舵机向左偏向,120°、150°、180°等,如接收到5-9信号,则舵机向右偏向,60°、30°、0°等。

  • 舵机初始化
    这里以定时器A0的通道三为例,如下代码:

	    /*初始化引脚*/MAP_GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P2, GPIO_PIN6, GPIO_PRIMARY_MODULE_FUNCTION);Timer_A_PWMConfig TimA0_PWMConfig;/*定时器PWM初始化*/TimA0_PWMConfig.clockSource = TIMER_A_CLOCKSOURCE_SMCLK;             //时钟源TimA0_PWMConfig.clockSourceDivider = psc;                            //时钟分频 范围1-64TimA0_PWMConfig.timerPeriod = ccr0;                                  //自动重装载值(ARR)TimA0_PWMConfig.compareRegister = TIMER_A_CAPTURECOMPARE_REGISTER_3; //通道三TimA0_PWMConfig.compareOutputMode = TIMER_A_OUTPUTMODE_TOGGLE_SET;   //输出模式                              MAP_Timer_A_generatePWM(TIMER_A0_BASE, &TimA0_PWMConfig); /* 初始化比较寄存器以产生 PWM1 */	
  • 角度控制
void SG90_angle(int a)
{int pwm=500+2000/180*a;MAP_Timer_A_setCompareValue(TIMER_A0_BASE, TIMER_A_CAPTURECOMPARE_REGISTER_3, pwm);
} 

四、停止线识别

  • 方法一
    通过判断有效色块的面积或者宽度,因为在巡线中都是1cm1cm的虚线组成,而停止线为5cm1cm,所以可通过色块的面积或者宽度等其他因素进行识别,返回停止信号。
w=max_ID.w()
if w>=80:uart.write("S")
  • 方法二
    因为整个赛图小车走的路程是固定的,则也可用通过小车走的路程进行停止。
if(sum>=1)
{Stop();PID_SetPoint(&L_pid,0);PID_SetPoint(&R_pid,0);			
}

五、技术交流

疑难解答或技术交流联系下方wx即可👇👇👇

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/12751.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

图像中不规则物体的长轴与短轴:OpenCV实现指南

1.首先&#xff0c;读取图像并将其转换为灰度图像。 2.进行图像预处理&#xff0c;包括使用高斯模糊和阈值化&#xff0c;以便更好地处理图像。 3.通过使用OpenCV的cv2.findContours()函数&#xff0c;找到图像中的所有轮廓。 4.遍历所有轮廓&#xff0c;如果轮廓点的数量大…

使用ajax进行前后端交互的方法

使用ajax进行前后端交互的方法&#xff1a;&#xff08;我只测试通了json对象作为参数的方式&#xff0c;其他方式我没有测试通过&#xff09; 1、前端方法&#xff1a; 传参方式&#xff1a;POST 请求类型&#xff1a;json对象 响应类型&#xff1a;json对象 function test() …

idea 里 controller service impl mapper xml 切换跳转快捷键

首先在controller层&#xff0c;对着接口点方法的方法上按着ctrl和鼠标左键&#xff0c;你会进入service层。 对着方法ctrlaltb不按鼠标&#xff0c;你会进入impl层。service层的方法上按ctrl和鼠标左键会回到controller&#xff0c;ctrlaltb不按鼠标也会进入到impl层,impl上的…

[Linux]线程基本知识

概念 进程 一个正在执行的程序&#xff0c;它是资源分配的最小单位 进程中的事情需要按照一定的顺序逐个进行 进程出现了很多弊端: 一是由于进程是资源拥有者&#xff0c;创建、撤消与切换存在较大的时空开销&#xff0c;因此需要引入轻型进程&#xff1b; 二是由于对称多…

localhost和127.0.0.1一样吗?

学习笔记&#xff0c;如有错误&#xff0c;感谢指出&#xff01; 文章目录 1. 对比方式一1.1 表示方式&#xff1a;1.2 主机名解析&#xff1a;1.3 IPv6 支持&#xff1a;1.4 可读性和易用性&#xff1a;1.5 小总结 2. 对比方式二2.1 原理不同2.2 概念不同2.3 指向不同 1. 对比…

C++:类和对象(下)---对类和对象深入一些的理解

文章目录 构造函数&#xff1f;初始化列表explicit关键字 匿名对象 构造函数&#xff1f; 初始化列表 前面已然介绍过构造函数&#xff0c;但并未完全结束&#xff0c;构造函数有很多种写法&#xff0c;有带缺省参数的&#xff0c;有全缺省的&#xff0c;不带缺省参数的…但用…

未来的算法备案法规:创新和安全如何兼顾?

随着科技的快速发展&#xff0c;算法正逐步渗透到我们生活的各个方面&#xff0c;从推荐引擎到自动驾驶&#xff0c;从医疗诊断到金融交易&#xff0c;这一现象既充满希望&#xff0c;也充满了挑战。其中一个关键的挑战就是如何设计和实施有效的算法备案法规&#xff0c;以促进…

Linux下查找python路径

本地目前装了几个版本的python&#xff0c;这里记录下查找python路径的方法。 1&#xff1a;whereis命令 whereis python2&#xff1a;which命令 which python与whereis相似&#xff0c;但which会返回第一个找到的执行文件的位置。 3&#xff1a;find命令 find命令可以搜索系…

web流程自动化详解

今天给大家带来Selenium的相关解释操作 一、Selenium Selenium是一个用于自动化Web浏览器操作的开源工具和框架。它提供了一组API&#xff08;应用程序接口&#xff09;&#xff0c;可以让开发人员使用多种编程语言&#xff08;如Java、Python、C#等&#xff09;编写测试脚本&…

题目:2206.将数组划分成相等数对

​​题目来源&#xff1a; leetcode题目&#xff0c;网址&#xff1a;2206. 将数组划分成相等数对 - 力扣&#xff08;LeetCode&#xff09; 解题思路&#xff1a; 先对数组进行排序&#xff0c;然后判断从第 2i 个 与 第 2i1 个元素是否全部相等即可&#xff08;i0,1,2,3,4..…

需求分析案例:消息配置中心

本文介绍了一个很常见的消息推送需求&#xff0c;在系统需要短信、微信、邮件之类的消息推送时&#xff0c;边界如何划分和如何设计技术方案。 1、需求 一个系统&#xff0c;一般会区分多个业务模块&#xff0c;并拆分成不同的业务系统&#xff0c;例如一个商城的架构如下&am…

webpack基础配置

webpack基础 webpack 处理css兼容问题webpack 处理css闪屏问题webpack 优化压缩css代码总结webpack 两种开发模式webpack 基本的功能webpack配置 5概念devServer 生产环境webpack配置实例开发环境webpack配置实例webpack优化 webpack 处理css兼容问题 下载loader 引入 package…

day45-Netflix Mobile Navigation(左边侧边栏动态导航)

50 天学习 50 个项目 - HTMLCSS and JavaScript day45-Netflix Mobile Navigation&#xff08;左边侧边栏动态导航&#xff09; 效果 index.html <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name&…

k8s集群安装v1.20.9

参考网上资料并将异常问题解决&#xff0c;经测试可正常安装集群。 1.我的环境准备 本人使用vmware pro 17新建三个centos7虚拟机&#xff0c;每个2cpu&#xff0c;20GB磁盘存储&#xff0c;内存2GB&#xff0c;其中主节点的内存3GB&#xff0c;可使用外网. 2.所有节点安装D…

33. 本地记事本

本地记事本 html部分 <button class"add"><i class"iconfont icon-jiahao"></i> </button>css部分 *{margin: 0;padding: 0; } body{background-color: #7bdaf3;display: flex;padding-top: 3rem;flex-wrap: wrap; } .add{pos…

每日一题——删除有序数组中的重复项

删除有序数组中的重复项 题目链接 注&#xff1a;本题所采用的方法是建立在移除元素的基础之上的&#xff0c;如果大家对双指针的方法不大了解&#xff0c;或者不会做《移除元素》这一题&#xff0c;建议先去看看&#x1f449;传送门 具体步骤 定义两个指针slow和fast&#…

【计算机网络】传输层协议 -- UDP协议

文章目录 1. 传输层相关知识1.1 端口号1.2 端口号范围划分1.3 知名端口号1.4 一些相关命令 2. UDP协议2.1 UDP协议格式2.2 UDP协议的特点2.3 什么是面向数据报2.4 UDP的缓冲区2.5 UDP使用注意事项2.6 基于UDP的应用层协议 1. 传输层相关知识 传输层是计算机网络中的一个重要层…

【如何训练一个中英翻译模型】LSTM机器翻译模型部署之onnx(python)(四)

系列文章 【如何训练一个中英翻译模型】LSTM机器翻译seq2seq字符编码&#xff08;一&#xff09; 【如何训练一个中英翻译模型】LSTM机器翻译模型训练与保存&#xff08;二&#xff09; 【如何训练一个中英翻译模型】LSTM机器翻译模型部署&#xff08;三&#xff09; 【如何…

云原生架构

1. 何为云原生&#xff1f; 很多IT业内小伙伴会经常听到这个名词&#xff0c;那么什么是云原生呢&#xff1f;云原生是在云计算环境中构建、部署和管理现代应用程序的软件方法。 当今时代&#xff0c;众多企业希望构建高度可扩展、灵活且有弹性的应用程序&#xff0c;以便能够快…

OAID学习

为了在包含用户隐私的同时&#xff0c;让广告商可以了解用户在应用中的行为&#xff0c;安卓系统提供了OAID&#xff08;Open Anonymous Device Identifier&#xff09;用来跟踪设备。OAID是一种非永久的、近似唯一的设备标识符&#xff0c;由字母和数字组成&#xff0c;长度不…