CUIT智能车竞赛总结

作为一名大一的学生,CUIT智能车竞赛是我参加的第一个有关于电子方面的比赛,虽然最终我们的智能车没有成绩,但还是有所收获,并因此写了这个总结。

做一辆能够自动寻迹的智能车,需要

①车模

②两个电机

电机的驱动方法:用l298n模块,用单片机输出两路电压,一路输出高电平一路输出低电平,并输出一路PWM波,来驱动一个电机,改变PWM占空比可以改变电机转动的速度。

启动电机的代码:

__HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_1,DJ);

__HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_2,DJ);

(DJ为设置的占空比)

③l298n模块(用于驱动电机)

④一个舵机(用于智能车转弯),舵机有三根线:VCC(红线),GND(棕线),信号线(黄线)。使用电压3-7.2V,但一般接5V以上才能驱动。PWM占空比为2.5%时为0°,每增加2.5%,增加45°。

⑤干簧管(用于停车)

⑥蓝牙模块(用于调试,)

⑦需要硬件员画电磁杆(用于检测电压变化)和底板(用于升压和放置核心板,减少杜邦线的使用)

⑧需要一块STM32核心板(我用的是STM32F103C6T6)。

做智能车需要三人组队,在队伍中我是一名软件员,任务就是写代码,让我们的智能车能够成功寻迹。

1.ADC采集

   因为我们的电磁杆的问题,我们的八字电感没有办法使用,所以只能使用竖直和水平电感(各需要两路ADC),因为还要干簧管检测停车,所以又加了一路ADC采集,在某一次调试过程中,有小伙伴告诉我加一路中间电感可以很快地判断三岔路和环岛,因此我的硬件员又加了一路中间电感,我一共开了6路ADC,相关配置如下图。

 (添加ADC的时候我经常会忘记改“Number”,所以一定要记住添加ADC的时候要改相关的配置!)

uint16_t adc_buff[6];

HAL_ADC_Start_DMA(&hadc1,(uint32_t *)adc_buff,6);

 一篇较好的对ADC介绍和使用的文章:http://t.csdn.cn/HqMP3

 2.滤波

我用的是平均数滤波。

void Average_Value(void)//滤波
{
	
	int i,sum0=0,sum1=0,sum2=0,sum3=0,sum4=0,sum5=0;
	
		for(i=0;i<10;i++)
		{
			adc0[i]=adc_buff[0];
			sum0=sum0+adc0[i];
		}
		x0=sum0/10;
		
		for(i=0;i<10;i++)
		{
			adc1[i]=adc_buff[1];
			sum1=sum1+adc1[i];
		}
		x1=sum1/10;
		
		for(i=0;i<10;i++)
		{
			adc2[i]=adc_buff[2];
			sum2=sum2+adc2[i];
		}
		x2=sum2/10;
		
		for(i=0;i<10;i++)
		{
			adc3[i]=adc_buff[3];
			sum3=sum3+adc3[i];
		}
		x3=sum3/10;
		
		for(i=0;i<10;i++)
		{
			adc4[i]=adc_buff[4];
			sum4=sum4+adc4[i];
		}
		x4=sum4/10;
		
		for(i=0;i<10;i++)
		{
			adc5[i]=adc_buff[5];
			sum5=sum5+adc5[i];
		}
		x5=sum5/10;
}

3.归一化

定义:把需要处理的数据经过处理后,限制在你所需要的一定范围内。首先归一化是为了后面处理数据的方便,其次是保证程序运行时收敛加快。

归一化的具体作用是归纳统一样本的统计分布性,使用归一化可以提高智能车对各个不同赛道的兼容性。

归一化的公式:x=(x-Min)/(Max-Min)

我的相关代码:

x1=(x1-Min)/(Max-Min);//归一化
x2=(x2-Min)/(Max-Min);
x3=(x3-Min)/(Max-Min);
x4=(x4-Min)/(Max-Min);

4.差比和

差比和的公式:ARR=(R-L)/(R+L)

由于采集电感值时,时刻保持小车位于赛道正中,故还需要研究小车位于内环与外环的差异。由于小车左、右水平电感(L,R)受到小车左、右位置影响不大,而受小车前、后位置影响较大,采取固定L、R值的方式来确认小车的位置,并研究输出误差err算出的ARR即误差)。算出的误差再经过PID作用来控制舵机转动,使小车始终保持在中心线上。

我的代码:

float Level_Output(void)//水平差比和
{
	L=  (x1-x2) / (x1+x2);
	L=L*500;
	return L;
}
float Erect_Output(void)//竖直差比和
{
	R= (x3-x4) / (x3+x4);
	R=R*500;
	return R;
}

差比和算出来的值可适当放大,具体放大多少由自己决定,得到的值可直接给PID使用,从而直接控制舵机的角度变化。

注:x1,x2,x3,x4定义时应定义为float

5.PID

P:比例项 输入偏差乘以一个常数

I: 积分项 对输入偏差进行积分运算

D:微分项 对输入偏差进行微分运算

将比例、积分、微分三种调节规律结合在一起, 只要三项作用的强度配合适当,既能快速调节,又能消除余差,可得到满意的控制效果。

一篇学长推荐的对PID较详细的解释:PID应用详解 - -零 - 博客园

我在做智能车的过程中,仅使用了PD,下面是我的代码

static float PID(float error)
{
	float Return;
	
	Return = P*error + D*(error-Last_error);
	Last_error=error;
	
	return Return;
}
float PID_Init(float error)
{
	float Return;
	
	 P=0.7;
	 D=0.55;	
	
	Return=PID(error);
	if(Return< -200)
	{
		return -200;
	}
	if(Return > 200)
	{
		return 200;
	}
	
	return Return;
}

调节P时的响应作用比较大,调节D时的响应作用比较小,在具体调节过程中可根据实际情况来调节P和D的数值。

PID的error即为差比和函数的返回值,PID的返回值给舵机来控制舵机的转动。

6.出库

智能车比赛规则需要智能车自己出库和入库

关于入库,我就设置了一个标志位,刚开始让舵机转动一个角度,延时一段时间后转回来,然后改变标志位的值,成功完成了出库。我的代码:

int b=1;

if(b==1)//出库
{
	__HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_4,800);//¶æ»ú
	HAL_Delay(1500);
	b=0;
}

7.入库

入库需要使用干簧管检测停车,我使用的是外部中断,干簧管遇到磁铁会检测到有下降沿产生,进入中断,标志位加一,因为要跑两圈,所以待标志位加到2时再强制打角使小车入库并关闭电机。

CubeMx相关配置

 

中断:

(放在it.c中)

int stop=0;

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	if(GPIO_Pin==GPIO_PIN_1)
	{
		stop++;
	}
}

 入库:

(放在while循环里)

if(stop==2)//入库
{
	DJ=0;
	__HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_4,800);
	HAL_Delay(1000);
	__HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_1,DJ);
	__HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_2,DJ);
}

8.三岔路和环岛

加了一路中间电感之后,我本来想试一下能不能进三岔路和环岛,但出库入库是临时通知的,没有出库和入库就直接没有成绩,无奈之下最后一天我只能先去搞定出库和入库,没有去使用那一路中间电感来检测三岔路和环岛。

思路:

环岛是利用检测到的电压的变化特点来进入和出来环岛。

三岔路是检测导归一化后的值突然变小,控制舵机转动一个角度进入一边三茬路,第二圈检测到时向另一边打角。

9.蓝牙

我调试的时候OLED不能显示,串口助手也不能打印,因此只能用蓝牙来调试,我用的是手机上的蓝牙调试器,非常方便。

打印函数:

int fputc(int ch, FILE *f)
{
	HAL_UART_Transmit(&huart1,(uint8_t *)&ch,1,0xffff);
	return ch;
}

10.比赛

比赛时,4分钟调试时间的时候,电机无故不转动,调试时间过去以后电机才开始转动,我们就让它跑,跑的时候,智能车很抖,第一圈便冲出赛道三次,我想下较为稳妥的代码时,比赛时突然发现自己的代码编译有错误,导致我们无法下载代码,最后用的就是车里原有的代码,时间到了没有完成两圈的寻迹。

赛后我回来检查我的代码,发现是因为我在it.c里定义的用于检测停车的标志位用了static int,这时候这个变量将不能在另外的.c文件里使用,因而程序会报错。

此次智能车竞赛告诉我,平时应多学一些知识,在比赛前不应该再去改动代码,就算改动了也应该提前编译,在赛前提前把需要用的代码打开,下载的时候能够立马下载,组内成员应该积极配合,多交流,软件员和硬件员之间也应该不断的交流,只有团队共同努力才能把比赛做好。

  • 19
    点赞
  • 79
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值