STM32寻迹智能车

  • STM32寻迹智能车
    • 一.电磁巡线传感器
      • 1.归一化的概念
      • 2.归一化的原因
      • 3.归一化步骤
      • 4.算术平均值滤波
    • 二.线性CCD
      • 1.图像二值化
      • 2.识别直道
      • 3.识别弯道
    • 三.编码器
    • 四.速度闭环控制

上传这个是想记录一下,原文链接暂时没有,侵删。

STM32寻迹智能车

一.电磁巡线传感器

1.归一化的概念

归一化处理,由于各个电感的性能特性存在很大差异特别是电压波动范围相差较大。因此为了给算法制定统一的标准给数据处理带来方便须对A/D传感器采集来的信号做归一化处理。
具体方法是通过公式将各传感器电压值都处理成相对该传感器最大电压和最小电压使得传感器输出电压值都保持在0到100之间。

2.归一化的原因

假设不用归一化处理时,距离中线零偏差时,电感A的值是1000,偏离赛道20厘米时,电感A值是200.当赛道电源不准时,比如输出电流由100ma变成了120ma,这时,电感A在零偏差的值和偏离赛道20厘米时候的值都会变大,设分别变成了1200和240,这时,你设定的阈值会出问题了。比如,你设置在电感A值小于等于200的时候(偏差20cm)判定丢线,电流变大之后,偏差为20cm,A电感值为240,大于了200,这时本来该判丢线,却没法判丢线了,车辆路径就相应会变化

这样的处理算法,其本质其实就是在每次车跑之前,重新快速校准偏差和电感值的对应关系。

3.归一化步骤

信号归一化的方法如下:求取电压值最大的传感器位置,然后和它周围两个传感器采样值进行加权计算即可求得小车的偏差。

Sensor_Left =   analogRead(1);    //左边电感采集值
Sensor_Middle = analogRead(2);    //中间电感采集值
Sensor_Right =  analogRead(3);    //右边电感采集值
if (Sensor_Left + Sensor_Middle + Sensor_Right > 25)
{sum = Sensor_Left * 1 + Sensor_Middle * 50 + Sensor_Right * 99; //归一化处理Sensor = sum / (Sensor_Left + Sensor_Middle + Sensor_Right);    //求偏差
}

4.算术平均值滤波

通过连续记录数个传感器值,经过排序后去掉最大值与最小值,剩余数进行平均。

//算数平均值滤波
uint16_t AD_Filter(u8 ch)
{  uint16_t ADC_Value[7];uint16_t ADC_Average[1];int i,j,t;for(i=0;i<7;i++){   ADC_Value[i]= Get_ADC(ch); }for(i=0;i<6;i++)    {for(j=0;j<6-i;j++){if(ADC_Value[j]>ADC_Value[j+1]){t=ADC_Value[j+1];ADC_Value[j+1]=ADC_Value[j];ADC_Value[j]=t;}}}ADC_Average[0]=(uint16_t)((ADC_Value[1]+ADC_Value[2]+ADC_Value[3]+ADC_Value[4]+ADC_Value[5])/5.0);   return ADC_Average[0];
}

二.线性CCD

线性CCD相当于集成了一排灰度模块的传感器。

线性CCD的核心是由一行光电二极管(每个光电二极管都有各自的积分电路,此电路统称为像素)组成的感光阵列,阵列后面有一排积分电容,光电二极管在光能量冲击下产生光电流,构成有源积分电路,那么积分电容就是用来存储光能转化后的电荷。积分电容存储的电荷越多,说明前方对应的那个感光二极管采集的光强越大,当光强接近饱和时,像素点灰度趋近于全白,呈白电平。

由此可知线性 CCD提取信号是被动的接受反射回的光线,因此采集的信号易受外界环境的影响。

//初始化ccd
void  ccd_Init(void)
{
//先初始化IO口RCC->APB2ENR|=1<<2;    //使能PORTA口时钟 GPIOA->CRL&=0XFFFF0FFF;//PA3 anolog输入     GPIOA->CRL&=0X0FFFF0FF;//PA2   7 GPIOA->CRL|=0X20000200;//Pa2   7 推挽输出 2MHZ   //通道10/11设置           RCC->APB2ENR|=1<<9;    //ADC1时钟使能      RCC->APB2RSTR|=1<<9;   //ADC1复位RCC->APB2RSTR&=~(1<<9);//复位结束      RCC->CFGR&=~(3<<14);   //分频因子清零   //SYSCLK/DIV2=12M ADC时钟设置为12M,ADC最大时钟不能超过14M!//否则将导致ADC准确度下降! RCC->CFGR|=2<<14;           ADC1->CR1&=0XF0FFFF;   //工作模式清零ADC1->CR1|=0<<16;      //独立工作模式  ADC1->CR1&=~(1<<8);    //非扫描模式   ADC1->CR2&=~(1<<1);    //单次转换模式ADC1->CR2&=~(7<<17);      ADC1->CR2|=7<<17;     //软件控制转换  ADC1->CR2|=1<<20;      //使用用外部触发(SWSTART)!!! 必须使用一个事件来触发ADC1->CR2&=~(1<<11);   //右对齐    ADC1->SQR1&=~(0XF<<20);ADC1->SQR1&=0<<20;     //1个转换在规则序列中 也就是只转换规则序列1                //设置通道7的采样时间ADC1->SMPR2&=0XFFFF0FFF;//通道3采样时间清空    ADC1->SMPR2|=7<<9;      //通道3  239.5周期,提高采样时间可以提高精确度     ADC1->CR2|=1<<0;     //开启AD转换器    ADC1->CR2|=1<<3;        //使能复位校准  while(ADC1->CR2&1<<3);  //等待校准结束           //该位由软件设置并由硬件清除。在校准寄存器被初始化后该位将被清除。          ADC1->CR2|=1<<2;        //开启AD校准    while(ADC1->CR2&1<<2);  //等待校准结束delay_ms(1);
}

1.图像二值化

线性 CCD 如果扫到白线 AD 值即为一个较高的电压值(接近 3v),扫到黑线即为一个较低的电压值。

为了准确判断黑线的位置以及减弱赛道上噪点的干扰,需将 CCD 采集的图像进行二值化处理,把模拟信号转换成 0 和 1 的二值信号,便于后期的数据处理。

2.识别直道

赛道引导线处于赛道两边,在进行边缘检测时(即扫描像素二值化之后 0 和 1 的跳变沿),可通过从中心向两边扫描的方式实现,从左右两边同时寻找从 1 跳变到 0的像素点位置,具体过程为第 64 个像素点向第 1 个像素点扫描,得到左边引导线的位置Error_L,第 65 个像素点向第 128个像素点扫描,得到右边引导线的位置 Error_R,Error_L和 Error_R 符号相反。从中心到两边分别取值为 64 ~ 1和 - 64 ~ - 1,赛道偏差 Error = Error_L + Error_R。

由于线性 CCD 采回的数据在左右两个边沿不准确,所以左右各略去 4 个点,使用 120 个点的数据,此时 60 即为期望的中心值。

3.识别弯道

由于小车驱动电机的反应具有滞后性, 高速行驶于弯道时容易出现第 64 个像素点与第 65 个像素点同时落在黑线上的情况。此时从中心到两边像素点都没有从 1 到 0 的跳变, Error 就为 0, 从而出现丢线的情况。

为了避免这种情况的发生, 采用浮动中心点的方法, 即扫描并不是固定的从第 64 和 65 个像素点向两边进行, 而是根据上一次的赛道偏差计算出本次扫描的起始位置。

当小车处于左转弯时扫描起始位置向左移动, 反之向右移动,这样可以很好地避免了因扫描中心点落在黑线上而导致的丢线。

未完成编程…
说一说看到其他组的现象,实战中光源不可控,ccd容错率低,比赛中不容易调试,可以考虑自备光源。

三.编码器

光电编码器是一种通过光电转换将输出轴上的机械几何位移量转换成脉冲或数字量的传感器。光电编码器是由光码盘和光电检测装置组成。光码盘是在一定直径的圆板上等分地开通若干个长方形孔。由于光电码盘与电动机同轴,电动机旋转时,检测装置检测输出若干脉冲信号,为判断转向,一般输出两组存在一定相位差的方波信号。
霍尔编码器是一种通过磁电转换将输出轴上的机械几何位移量转换成脉冲或数字量的传感器。霍尔编码器是由霍尔码盘和霍尔元件组成。霍尔码盘是在一定直径的圆板上等分地布置有不同的磁极。霍尔码盘与电动机同轴,电动机旋转时,霍尔元件检测输出若干脉冲信号,为判断转向,一般输出两组存在一定相位差的方波信号。

四倍频
通过软件的方法实现四倍频时。正常情况下使用M法测速的时候,会通过测量单位时间内A相输出的脉冲数来得到速度信息。常规的方法,只测量A相(或B相)的上升沿或者下降沿,这样就只能计数3次。而四倍频的方法是测量A相和B相编码器的上升沿和下降沿。这样在同样的时间内,可以计数12次(3个1234的循环)。这就是软件四倍频的原理。

采集编码器数据
STM32定时器初始化为编码器模式

//把TIM2初始化为编码器接口模式
void Encoder_Init_TIM2(void)
{NVIC_InitTypeDef NVIC_InitStruct;TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;  TIM_ICInitTypeDef TIM_ICInitStructure;  GPIO_InitTypeDef GPIO_InitStructure;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);//使能定时器2的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//使能PA端口时钟GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3; //端口配置 PA0 PA1 PA2 PA3GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入GPIO_Init(GPIOA, &GPIO_InitStructure);                         //根据设定参数初始化GPIOANVIC_InitStruct.NVIC_IRQChannel = TIM2_IRQn;  //定时器2中断NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;  //使能IRQ通道NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;//抢占优先级1 NVIC_InitStruct.NVIC_IRQChannelSubPriority = 3;       //响应优先级3NVIC_Init(&NVIC_InitStruct);TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);TIM_TimeBaseStructure.TIM_Prescaler = 0x0; // 预分频器 TIM_TimeBaseStructure.TIM_Period = ENCODER_TIM_PERIOD; //设定计数器自动重装值TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;//选择时钟分频:不分频TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//边沿计数模式 TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);  //初始化定时器TIM_EncoderInterfaceConfig(TIM2, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);//使用编码器模式3TIM_ICStructInit(&TIM_ICInitStructure); //把TIM_ICInitStruct 中的每一个参数按缺省值填入TIM_ICInitStructure.TIM_ICFilter = 10;  //设置滤波器长度TIM_ICInit(TIM2, &TIM_ICInitStructure);//根据 TIM_ICInitStruct 的参数初始化外设 TIMxTIM_ClearFlag(TIM2, TIM_FLAG_Update);//清除TIM的更新标志位TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);//使能定时器中断TIM_SetCounter(TIM2,0);TIM_Cmd(TIM2, ENABLE); //使能定时器
}

四.速度闭环控制

速度闭环控制即有速度反馈的控制,由编码器提供速度反馈。将反馈速度(即当前速度)与目标速度进行比较,目标速度大于当前速度则加大速度,目标速度与当前速度之差越大则加速度越大。

添加一个定时 10ms 读取编码器数值的函数10ms读取一次编码器(即100HZ)。电机减速比为20,电机自带的霍尔编码器精度为13,AB双相组合得到4倍频,则转1圈编码器读数为20*13*4=1040。电机转速=编码器读数*100/1040 (r/s)。由于电机本身误差,转1圈编码器读数可能不等于1040,这时可以添加误差系数。

int Velocity_FeedbackControl(int TargetVelocity, int CurrentVelocity)
{int Bias; //定义相关变量 static int ControlVelocity, Last_bias; //静态变量,函数调用结束后其值依然存在 Bias=TargetVelocity-CurrentVelocity; //求速度偏差 ControlVelocity+=Velcity_Kp*(Bias-Last_bias)+Velcity_Ki*Bias; //增量式 PI 控制器;Velcity_Kp*(Bias-Last_bias)作用为限制加速度;Velcity_Ki*Bias,速度控制值由 Bias 不断积分得到,偏差越大加速度越大 Last_bias=Bias; return ControlVelocity; //返回速度控制值
}

STM32寻迹智能车相关推荐

  1. 四轮寻迹智能车的设计(逐飞IMX-RT1064)

    四轮寻迹智能车的设计(逐飞IMX-RT1064) 目录 四轮寻迹智能车的设计(逐飞IMX-RT1064) 1.前篇 (1)adc (模数/数模转换) (2)pit(定时中断) (3)pwm(波特率) ...

  2. 【IoT】寻光智能车与循迹智能车

    1.寻光智能车 功能说明 智能寻光小车,智能识别光线强弱,实现小车永远向光最强的地方行走,到光源处小车自动停止.基本车体为三轮.二驱.双层机构.主控芯片采用最常用的51单片机: 驱动采用L9110驱动 ...

  3. 电磁循迹智能车基于stm32cubeMX、HAL库—我的第一辆智能车

    我的第一辆智能车-电磁循迹智能车 提示:本文适用于初学,想完成一个基础四轮车练练手者,大佬还请勿喷,不过欢迎提出意见,有纰漏之处我将及时纠正. 注:工程代码链接已贴在文末. 前言: 所用到的硬件平台: ...

  4. CUIT循迹智能车竞赛

    本人作为一名刚刚进入实验室的萌新,怀揣着紧张而又期待的心情参加了这次智能车比赛,虽然在比赛中有许多做的不足的地方,但也在比赛中学到了很多有用知识,下面是一些关于比赛的经验,分享给大家.(实物图和3D图 ...

  5. 循迹智能车红外模块的选取

    智能车红外模块的选取 大学校内智能小车比赛,在宿舍调试时用了挺多种红外传感器,使用的时候各有差异,后来才发现这个差异是因为地板不是白色(巡线是黑色)导致的,而且不可调的红外在反应时间上,比可调的灵敏一 ...

  6. 智能车竞赛技术报告 | 智能车视觉 - 中国矿业大学 - 会飞的车

    简 介: 本文以第十六届全国大学生智能车竞赛为背景,介绍了 AI视觉四轮智能车系统的软硬件结构和开发流程.采用大赛组委会指定的 C型车模,以恩智浦 32位微控制器 MIMXRT1064最小系统板作为核 ...

  7. 智能车竞赛技术报告 | 节能信标组 - 兰州交通大学 - 先锋队

    简 介: 本文以第十六届全国大学生智能车大赛为背景,介绍了兰州交通大学节能信标组在比赛中的实现方案.本次比赛采用了3D打印的自制车模,主控芯片采用了英飞凌的TC264芯片,软件平台采用的IAR.本文中 ...

  8. 基于CCD摄像头智能车分段PID控制算法设计

    自动寻迹智能车涉及到当前高技术领域内的许多先进技术,其中最主要的是传感技术.路径规划和运动控制.本课题是以飞思卡尔智能车竞赛为背景,以单片机作为核心控制单元,以摄像头作为路径识别传感器,以直流电机作为 ...

  9. 三天让车跑起来!stm32循迹车 —— 第一天:基本模块使用方法

    声明在前:本系列以程序设计为主,适用于刚学会32,想完成一个基本项目却不知道怎么上手的小伙伴.想学习硬件方面如:电路.画板等内容的朋友请不要在本系列耽误您的时间,关闭即可. 眼瞅着日子一天天地过去,学 ...

最新文章

  1. BZOJ1491: [NOI2007]社交网络(Floyd 最短路计数)
  2. 认识一下SAP的Area Menu
  3. mysql8.0.12插件_mysql 8.0.12 安装使用教程
  4. Linux 操作系统原理 — 文件系统 — 存储布局
  5. 【CF】142 Div.1 B. Planes
  6. 盒子模型,top和margin-top
  7. struct和byte[]相互转换(用Marshal类实现)
  8. JavaScript之局部变量和局部函数
  9. WinAPI 字符及字符串函数(12): lstrlen - 串长度
  10. Android进阶——性能优化之APP启动速度优化实战总结(三)
  11. php 自定义函数转字母大小,PHP自定义函数实现文字到拼音转换功能
  12. .net接入微信二维码支付(模式二)
  13. i7服务器cpu型号推荐,CPU型号那么多 详细数据教你选_键鼠新闻-中关村在线
  14. 低延时直播系统开发技术方案
  15. 十一课堂|通过小游戏学习Ethereum DApps编程(1)
  16. css小游戏,js小游戏,Flex Box青蛙、冒险游戏、设计模式游戏等
  17. c 语言 模板函数参数,深入解析C++中的函数模板和函数的默认参数
  18. error怎么开机 fan_电脑开机提示CPU Fan Error是什么意思?如何解决?
  19. vue双向绑定经典案例
  20. 人工智能-高等数学之偏导数与梯度

热门文章

  1. Java入门123:一个老鸟的Java学习心得(二维码版)
  2. 【点宽专栏】破解波动性突破实盘系统
  3. 最适合程序猿的个性签名
  4. linux中seliunux配置文件,SELinux 入门简介
  5. 计算机名中文无法开机,处理win10电脑开机输入法中英文不能切换的图文
  6. python图案填充_用matplotlib用自定义图案填充多边形
  7. WLAN驱动分析文档_gzc126_新浪博客
  8. 二、Eureka服务注册与发现
  9. 百度地图查询周围建筑
  10. 会议信息 | BigBrain研讨会 September 21-23, CEST, 线上