题目
9187b07edca34322a2192830f28722c4.png

第一问:

按照题目要求,小车从A点走到B点,实际上就是走固定直线,可以衍生出以下几种方案,声光提示想必大家都会,这里不做赘述

方案一:速度环+位置环

原理:

利用速度环来控制两个轮子编码器数值(速度)一致,因此可以控制小车方向,利用位置环控制小车路程长短,使小车移动固定距离,但此方案属于开环方案

代码:

这里分享最简单的速度环+位置环代码

/*
	第一个参数为电机1目标编码器值
  第二个参数为电机2目标编码器值
	总编码器脉冲值
 */
void speed(int a,int b,int number)
{
	float Kp=0,Ki=1;	//设置参数根据现象调整,也可以设置两个KP,KI值+KD
	static int A,APwm,Last_A;
	static int B,BPwm,Last_B;
	
	while(abs(move)<number)//编码器脉冲绝对值
	{
		A=read1-a;    
		APwm+=Kp*(A-Last_A)+Ki*A;   
		Last_A=A;


		B=read2-b;
		BPwm+=Kp*(B-Last_B)+Ki*B;   
		Last_B=B;

//		OLED_Float(4,1,move,2);//显示

		limit(&APwm,&BPwm);//PWM限幅
		delay_ms(2);		//加延时,不然驱动会发烫
		load(APwm,BPwm);//加载PWM
	}
	load(0,0);//停止
	
	A=0;APwm=0;Last_A=0;
	B=0;BPwm=0;Last_B=0;
	
	move=0;//归0
	lenth=0;//归0
	
	stop();
	delay_ms(1000);
}

方案二:角度环+位置环

原理:

利用陀螺仪角度来设计角度环来控制控制小车方向,使小车方向稳定,利用位置环控制小车路程长短,使小车移动固定距离

代码:

这里分享最简单的角度环+位置环代码

//角度环
int erect(void)
{
	static float Kp=120,Ki=0.5;	
	int PWM_out;
	
	mpu_dmp_get_data(&Pitch,&Roll,&Yaw);			//获取数据
	
	PWM_out=Kp*(Roll-Med_Angle)+Ki*(gyroy-0);//根据实际的方位角计算
	return PWM_out;
}
void angle(int number)
{
	static int APwm,BPwm;
	int ect;
	while(abs(move)<number)//位置环
	{
		ect=erect();//角度环
		
		APwm=ect+1200;//加载前进速度,也可加载速度环
		BPwm=-ect+1200;
		
		limit(&APwm,&BPwm);
		delay_ms(5);
		load(APwm,BPwm);
	}
	load(0,0);
	APwm=0;BPwm=0;
	
	move=0;
	lenth=0;
	
	stop();
	delay_ms(1000);
}

方案三:角度环+标志位反馈

原理:

在车头放一个红外传感器,当开始行驶后检测到黑线即到达环形区域停止(或再向前走一小段距离,使车头投影盖过顶点),即可实现闭环

代码:

这里分享最简单的角度环+标志位反馈代码

void angle2()
{
	static int APwm,BPwm;
	int ect;
	while(irget3()!=0)
	{
		ect=erect();//角度环
		
		APwm=ect+1200;//加载前进速度,也可加载速度环
		BPwm=-ect+1200;
		
		limit(&APwm,&BPwm);
		delay_ms(5);
		load(APwm,BPwm);
	}
	load(0,0);
	APwm=0;BPwm=0;
	
	move=0;
	lenth=0;
	
	stop();
	delay_ms(1000);
}

第二问:

原理:

在我看来第二问只是在第一问的基础上加上了弧形处理,按照题目要求不能用摄像头,所以在车头处安装两个红外,实现循线,当车头处没有黑线时,即红外标志位改变时,完成弧线行驶

方案:循迹闭环+标志位反馈

这里分享最简单的循迹代码

void xunji(void)
{	
	while(irget3()!=0)
	{
		if(irget2()==1&&irget1()==1)
		{
			load(1500,1500);//按照实际设计速度
		}
		if(irget1()==0&&irget2()==1)
		{
			load(1000,2000);//按照实际设计速度
		}
		if(irget1()==1&&irget2()==0)
		{
			load(2000,1000);//按照实际设计速度,也可闭环
		}
	}
	load(0,0);
	
	move=0;
	lenth=0;
	
	stop();
}

此代码只作为参考!参考!参考!!!!

不是说此代码在我的硬件上能跑,在你的硬件上就一定能跑,按照实际情况调试更改

本篇文章,是思路分享,不是帮你做一二问!!!

资料为STM32一二问代码和对应PCB板,需要资料私信我(可接指导)

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐