【STM32平衡小车】电磁巡线归一化算法(二)

本文探讨了归一化处理在电磁车控制算法中的重要性,阐述了归一化的原因、步骤及其实现方法。通过归一化处理,能够确保传感器数据在不同电源条件下的一致性,提高电磁车路径控制的稳定性和适应性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、归一化的概念

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

归一化之后的传感器数据如图所示横坐标表示距离中心线的距离单位是毫米,纵轴是电压值。

在这里插入图片描述

二、归一化的原因

假设不用归一化处理时,距离中线零偏差时,电感A的值是1000,偏离赛道20厘米时,电感A值是200.当赛道电源不准时,比如输出电流由100ma变成了120ma,这时,电感A在零偏差的值和偏离赛道20厘米时候的值都会变大,设分别变成了1200和240,这时,你设定的阈值会出问题了。比如,你设置在电感A值小于等于200的时候(偏差20cm)判定丢线,电流变大之后,偏差为20cm,A电感值为240,大于了200,这时本来该判丢线,却没法判丢线了,车辆路径就相应会变化了(当然,阈值判定的不一定是丢线,具体看个人算法)。如果用归一化处理,按上例的数据,当电流100ma时,偏差时,记录下电感A的“最大值”(这里不一定最大,不过把零偏差当做最大,具体不细说)为1000,把车移到偏差为20cm时,记录下“最小值”(跟最大同理,只是选个参考点)为200,这时,归一化公式算出值为0到1(即“归一”),偏差为零是,电感A归一值为1((1000-200)/(1000-200)),偏差20cm时,电感A归一值为0((200-200)/(1000-200)),这时,如同前例,你只需要设置阈值的归一值为0,则判定丢线,那么在赛道电源电流是120ma时,采用同样的处理,在偏差为20cm的时候,电感A归一值也为0((240-240)/(1200-240)),即电源变化对你的阈值已经没有影响了(这是理想化情况,实际考虑其他各种因素,会有很微弱的影响)。

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

通过归一化处理,能保证电磁车有更强的适应性,适应更宽的赛道电源电流参数,而路径将不容易受电源的不同而影响。

三、归一化步骤

将 AD值做归一化处理,即根据各个传感器接收赛道的最高电压和最低电压,计算出各个传感器的相对值,最后来计算黑线位置。

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

网上的一个参考例程

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);    //求偏差
}
Velocity = 35;                                                    //电磁巡线模式下的速度
Bias = Sensor - 50;                                               //提取偏差
Angle =Bias * 0.65 + (Bias - Last_Bias) * 0.1;                    //方向PID
//Angle = abs(Bias)*Bias * 0.02 + Bias * 0.074 + (Bias - Last_Bias) * 1;
Last_Bias = Bias; //上一次的偏差
一些帖子记录

归一化是纵向处理(即对各个探头的处理),差比和是横向处理(即对探头之间的处理)

差比和同样可以消除放大率的影响 基础放大倍数已经约掉 这一点和归一化没有区别。但是却不能消除不对称

每次把归一值和实际偏差从新对应,从而保证在不同电源下计算实际偏差误差小。

跑前测。最大最小只是参考点,只要每次在固定的实际偏差时测,就可以保证准确性。

我说的这种方法是本质是每次跑之前都重测电压值与实际偏离赛道的距离的对应,通过归一抵消掉电感值(电感值不再参加控制部分数据处理),使之适应不同的赛道电源。

差和比应该在电感信号对称\一致的前提下,意义才更大。

就像给尺子标刻度,你不需要一直重标刻度吧?你的0刻度也不一定要标在尺子最边缘吧?我们需要的只是一个准确的相对刻度。

运动过程的归一,除了两个电感范围之间的差比和,还没其他思路。

这篇贴的方法只是数据的调零和归一,相当于现场快速标定。左边最大时,右边距离中线25cm,右边最大时,左边距离中线25cm,设计一个方法校准就行了。竖着的就把车横过来再扫。

这里说的归一化采值是指传感器数据自动标定(校准),过程是归一的方法。差比和是跟这里的归一采值是可以并存的;差值与和值,都包含一个放大倍率,不考虑精度的情况下,分子分母把放大倍率约掉了;差比和不能解决不对称,因为传感器本身可能不对称,重新标定后,能极大的改善对称性。

参考:

1、http://www.znczz.com/thread-220290-1-1.html

2、http://www.znczz.com/thread-213532-1-2.html

<think>嗯,用户的问题是关于如何使用STM32实现电磁巡线小车电磁感应功能。首先,我需要理解电磁巡线的基本原理。电磁巡线通常是通过电感线圈检测交变磁场的变化,然后将这些信号处理后,由微控制器(比如STM32)进行判断,进而控制小车的运动方向。 用户提到的参考引用中有几个关键点。引用[1]和[2]提到了使用L298N电机驱动模块和四路或五路电磁传感器的布局。中间的电感用于三岔路检测,横置的用于正常循迹,斜置的用于环岛检测。这说明传感器的布局方式对功能实现很重要。引用[3]提到了归一化的概念,这可能涉及到信号处理步骤,比如将不同传感器的模拟信号进行归一化处理,以便于比较和判断。引用[4]则涉及电机驱动的测试方法,需要给L298N的引脚高低电平来控制电机。 接下来,我需要将这些信息整合成一个清晰的实现方案。首先,电磁感应的原理部分需要解释电感线圈如何感应交流磁场,产生电压信号,然后通过放大和滤波电路处理。接着,硬件设计部分应包括传感器布局、信号调理电路和电机驱动模块的连接。软件部分需要涉及ADC采样、信号处理(如归一化)、巡线逻辑判断(PID控制)以及电机控制。 可能用户没有明确提到的细节包括具体的电路设计参数,比如放大电路的增益设置,或者PID控制中的参数调整方法。这些可能需要进一步解释或提供示例。此外,归一化的具体实现方法,比如如何将不同传感器的ADC值映射到同一范围内,也是关键点。 还要考虑用户的实际应用场景,比如是否需要在复杂路径(如环岛、三岔路)中进行检测,因此传感器的布局和逻辑判断可能需要更复杂的处理。例如,引用[2]提到的五路电感摆放方式,可能需要不同的处理策略来应对不同路径情况。 最后,代码示例部分需要结合STM32的HAL库,展示如何读取ADC值、处理数据、判断方向并控制电机。需要注意的是,代码中的引脚配置需要根据实际硬件连接进行调整,同时PID控制可能需要用户自行调试参数。 可能生成的相关问题包括如何选择电感传感器、如何处理信号干扰、如何优化巡线算法等,这些都是用户在实现过程中可能遇到的后续问题。</think># STM32电磁巡线小车实现方案 ## 一、电磁感应原理 电磁巡线基于交流磁场感应原理,导线中通有$20kHz$的交流电时,电感线圈会感应出电动势$V=2πfL\cdot I$。线圈电压幅值与距离导线的位置相关,距离导线越近,感应电压越大[^2]。 ## 、硬件设计方案 ### 1. 传感器布局(五路电感推荐方案) $$L_1-L_5布局示意图$$ ```python # 传感器布局坐标示例 sensor_positions = [ (0, 0), # 中间电感(三岔路检测) (-3, 2), # 左横置电感 (3, 2), # 右横置电感 (-5, -1), # 左斜置电感(环岛检测) (5, -1) # 右斜置电感 ] ``` ### 2. 信号调理电路 | 电路模块 | 参数要求 | |---------|---------| | 放大电路 | 增益$100-200$倍 | | 带通滤波 | 中心频率$20kHz$ | | 检波电路 | 输出直流信号 | ### 3. 硬件连接 ```mermaid graph TD STM32-->L298N[L298N电机驱动] STM32-->ADC模块 电感线圈-->信号调理电路-->ADC模块 ``` ## 三、软件实现流程 ### 1. ADC采样配置 ```c // STM32CubeMX配置示例 hadc1.Instance = ADC1; hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4; hadc1.Init.Resolution = ADC_RESOLUTION_12B; hadc1.Init.ScanConvMode = ENABLE; ``` ### 2. 信号归一化处理 $$NormalizedValue = \frac{ADC_{raw} - ADC_{min}}{ADC_{max} - ADC_{min}}$$ 需进行动态校准获取极值[^3] ### 3. 巡线逻辑判断 ```c // 路径判断示例代码 if (left_sensor > threshold && right_sensor > threshold) { go_straight(); } else if (left_sensor > right_sensor) { turn_left(); } else { turn_right(); } ``` ### 4. 电机PID控制 $$u(t) = K_p e(t) + K_i \int_0^t e(\tau)d\tau + K_d \frac{de(t)}{dt}$$ ## 四、关键代码片段 ```c // 电磁信号读取示例 void GetSensorValues(void) { HAL_ADC_Start(&hadc1); for(int i=0; i<5; i++){ sensor_values[i] = HAL_ADC_GetValue(&hadc1); HAL_Delay(1); } HAL_ADC_Stop(&hadc1); } // 电机控制函数 void Motor_Control(int left, int right) { __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, left); __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_2, right); } ```
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ReCclay

如果觉得不错,不妨请我喝杯咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值