嵌入式玩小车车~循迹原理

主车循迹原理

1.找到can_user.c第168行左右的手机控制小车的循迹函数,如下:


case 0x06:              //主指令是0x06,代表主车循迹
				Stop_Flag = 0; Go_Flag = 0; wheel_L_Flag = 0;wheel_R_Flag = 0;wheel_Nav_Flag = 0;
				Back_Flag = 0; Track_Flag = 1;
				Car_Spend = Wifi_Rx_Buf[3];
				//set_Test_Times();
				break;


将其复制到drive.c,代码如下:


void Car_Track(uint8_t speed) //主车循迹函数 参数:速度
{
		Stop_Flag = 0;
		Go_Flag = 0; 
		wheel_L_Flag = 0;
		wheel_R_Flag = 0;
		wheel_Nav_Flag = 0;
		Back_Flag = 0; 
		Track_Flag = 1;
		Car_Spend = speed;
}


形式参数只有一个速度,原因是循迹无需给定小车要行驶多少码盘值,循迹的原理是让小车从任意位置,沿着黑线行驶至下个十字路口处,当循迹板扫描到黑线时,小车停止运行;或者从协议上看,循迹的主指令为0x06,对应的副指令只有速度值,没有码盘值。

我们还是通过Ctrl+F“Track_Flag”查找循迹的监测函数:

找到后,代码如下(my_lib→roadway_check.c→196行左右):



/**
	循迹监测
*/
void Track_Check()
{	
	if(Track_Flag == 1)
	{
		Track_Correct(Get_Host_UpTrack(TRACK_H8)); //调用下面的246行左右的循迹判断函数Track_Correct(); 获取循迹板的高八位状态
	}
}


调用循迹判断函数(246行左右),如下:



/***************************************************************
** 功能:     循迹判断函数
** 参数:	  无参数
** 返回值:   无
****************************************************************/
void Track_Correct(uint8_t gd) //参数代表循迹灯的状态
{
	if(gd == 0x00)	//0x00:0000 0000,为循迹灯全灭,代表小车已经到达十字路口位置,
	{	
		Track_Flag = 0; //循迹标志位赋值为0
		Stop_Flag = 1;  //运行状态标志位赋值为1,代表找到了十字路口,十字路口状态,通过通讯协议 四、竞赛平台运行状态表查看
		Send_UpMotor(0,0);  //调用底层电机驱动函数,使两个轮子的速度置0
	}
	else
	{
	   	Stop_Flag=0;  //将运行标志位赋值为0,代表正在循迹,迅疾状态,通过 协议四查看
		if(gd==0XE7||gd==0XF7||gd==0XEF)//0xE7:1110 0111或0xF7:1111 0111或0xEF:1110 1111 ,代表走的比较正,让他正常行驶
		{ 
			LSpeed=Car_Spend;
			RSpeed=Car_Spend;
		}
		if(Line_Flag!=2) //初始化Line_Flag = 0,所以此语句一定成立
		{		

			if(gd==0XF3||gd==0XFB) //oxF3:1111 0011 或 0xFB:1111 1011,代表小车偏离了黑线,车头向左偏、车尾向右偏了(文档有图)
			{ //通过 左轮速度+30、右轮速度-30 使小车回正
				LSpeed=Car_Spend+30;
				RSpeed=Car_Spend-30;
				Line_Flag=0;
			}
			else if(gd==0XF9||gd==0XFD)//0xF9:1111 1001 或 0xFD:1111 1101,代表车头向左、车尾向右的偏的更离谱了
			{ //通过 左轮速度+40、右轮速度-60 使小车回正
				 LSpeed=Car_Spend+40;
				 RSpeed=Car_Spend-60;				 
				 Line_Flag=0;
			}
			else if(gd==0XFC)//0xFC:1111 1100 //更更偏了
			{ //通过 左轮速度+50、右轮速度-90 使小车回正
				LSpeed = Car_Spend+50;
				RSpeed = Car_Spend-90;
				 Line_Flag=0;
			}
			else if(gd==0XFE)//0xFE:1111 1110 //更更更偏了
			{ //通过 左轮速度+60、右轮速度-120 使小车回正
				 LSpeed = Car_Spend+60;
				 RSpeed = Car_Spend-120;			
				 Line_Flag=1;
			}
		}//下面是向左偏的if语句
		if(Line_Flag!=1) //如果达到向右最偏的状态,就不用判断此if语句了,跳过。
		{
			if(gd==0XCF)//0xCF:1100 1111 车头向右偏、车尾向左偏了
			{ 
				 RSpeed = Car_Spend+30;
				 LSpeed = Car_Spend-30;
				 Line_Flag=0;
			} 
			else if(gd==0X9F||gd==0XDF)//0x9F:1001 1111或 0xDF:1101 1111,代表车头向右、车尾向左偏的更离谱了
			{ 
				 RSpeed = Car_Spend+40;
				 LSpeed = Car_Spend-60;
				 Line_Flag=0;
			} 			  
			else if(gd==0X3F||gd==0XBF)//0x3F:0011 1111 或 0xBF:1011 1111 更更偏了 
			{ 
				 RSpeed = Car_Spend+50;
				 LSpeed = Car_Spend-90;
				 Line_Flag=0;
			} 
			else if(gd==0X7F)//0x7F:0111 1111 更更更偏了	 	
			{ 
				 RSpeed = Car_Spend+60;
				 LSpeed = Car_Spend-120;
				 Line_Flag=2;
			}			
		}
		if(gd==0xFF)   //0xFF:1111 1111,代表循迹灯全亮,意思就是小车的位置跟黑线没关系了,那我们就让他执行下列操作
		{
			if(count > 1000)  //计1000次,完了停车。
			{
					count=0;
					Send_UpMotor(0,0);
					Track_Flag=0;
					if(Line_Flag ==0) 
						Stop_Flag=4;
			}	
			else 
				count++;				
		}
		else 
			count=0;
	}
	if(Track_Flag != 0) //LSpeed和RSpeel初始化为0,如果出现三个灯同时灭的状态,则上面的if语句都将不满足,导致小车不会动;所以需要在drive.c里加上一条控制速度语句
	{
			Control(LSpeed,RSpeed);
	}
}


(完)