主车循迹原理
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);
}
}