公司动态
基于QTI传感器的自主巡线小车实现
这是一台能沿着预设黑色轨迹自主巡游的机器人它在“深圳”地图上依次经过12个“景点”并在每个景点自动掉头最终回到起点。项目核心是一块搭载51单片机的BoeBot小车配合4路QTI灰度传感器通过状态机决策实现路径跟踪、路口识别和转向控制。传感器4路QTI红外反射式传感器连接至P1.4~P1.7高四位输出数字电平0黑线1白底#includeuart.h #includeBoeBot.h void Follow_Line(void); int Get_4QTI_State(void); void MoveAStep(int LeftP,int RightP); void RightTurn(int steps); void LeftTurn(int steps); void Rotate(int steps); void Forward(int steps); int right90Steps42;//向右转90度所需的循环次数 int left90Steps33;//向左转90度所需的循环次数 int UTurnSteps45;//旋转180度所需的循环次数 int whereamI0;//经过的景点数 int crossSteps8,j1,k1; void main(void) { uart_Init(); delay_nms(2000);//延时2s,消除打开开关对小车的影响 while(1) { Follow_Line(); } } void Follow_Line(void) { int QTIState; int LeftPulse,RightPulse; QTIStateGet_4QTI_State();//获取小车的状态 switch(QTIState) { case 0x10 : LeftPulse1700;RightPulse1700;break;//右转 0001 case 0x30 : LeftPulse1700;RightPulse1500;break;//小幅右转 0011 case 0x20 : LeftPulse1550;RightPulse1450;break;//前进 0010 case 0x40 : LeftPulse1550;RightPulse1450;break;//前进 0100 case 0x60 : LeftPulse1550;RightPulse1450;break;//前进 0110 case 0x80 : LeftPulse1300;RightPulse1300;break;//左转 1000 case 0xc0 : LeftPulse1500;RightPulse1300;break;//小幅左转 1100 case 0xe0 : // 1110 if(whereamI8k1) { RightTurn(right90Steps); LeftPulse1500;RightPulse1500;k;break; } //经过景点8后到达十字路口非理想状态下未检测到“1111”而是检测到“1110”为保证准确也让其右转 else if(whereamI2||whereamI4||whereamI10) { RightTurn(right90Steps); LeftPulse1500;RightPulse1500;break; }//经过景点2、4、10后到达丁十字路口非理想状态下未检测到“1111”而是检测到“1110”为保证准确也让其右转 else if(whereamI5) { Forward(crossSteps);LeftPulse1500;RightPulse1500;break; }//经过景点5后到达十字路口时, 非理想状态下未检测到“1111”而是检测到“1110”为保证准确也让其直行 else { LeftTurn(left90Steps); LeftPulse1500;RightPulse1500;break; } case 0x70: if(whereamI8k1) // 0111 { RightTurn(right90Steps); LeftPulse1500;RightPulse1500;k;break; }//经过景点8后到达十字路口时, 非理想状态下未检测到“1111”而 是检测到“0111”为保证准确也让其右转 else if(whereamI8k2) { LeftTurn(left90Steps);LeftPulse1500;RightPulse1500;break; }//经过景点8后再经过一个十字路口到达第二个十字路口时非理想状态下未检测到“1111”而是“0111”为保证准确也让其左转 else if(whereamI10||whereamI5) { Forward(crossSteps);LeftPulse1500;RightPulse1500;break; }//经过景点10后到达第二个丁字路口时使其直行经过景点5后非理想状态下检测到“0111”为保证准确也让其直行 else { RightTurn(right90Steps);LeftPulse1500;RightPulse1500;break; } case 0xf0 : switch(whereamI) //1111 { case 5:Forward(crossSteps);LeftPulse1500;RightPulse1500;break; //经过景点5后到达十字路口时使其直行 case 6: if(j1) { LeftTurn(left90Steps); LeftPulse1500;RightPulse1500;j;break; }//经过第6个景点到达第1个十字路口时使其左转 else { RightTurn(right90Steps); LeftPulse1500;RightPulse1500;break; }//经过第6个景点到达第2个十字路口时使其右转 case 8: if(k1) { RightTurn(right90Steps); LeftPulse1500;RightPulse1500;k;break; }//经过第8个景点到达第1个十字路口时使其右转 else { LeftTurn(left90Steps); LeftPulse1500;RightPulse1500;break; }//经过第8个景点到达第2个十字路口时使其左转 case 9: case 12 : LeftTurn(left90Steps); LeftPulse1500;RightPulse1500;break; //经过第9个或第12个景点后到达十字路口时使其左转 default :RightTurn(right90Steps); LeftPulse1500;RightPulse1500;break; }break; case 0x00: switch(whereamI) // 0000 { case 12 :Forward(12);Rotate(40);delay_nms(20000); LeftPulse1500;RightPulse1500;break; //游完所有景点后到达起始点时先直行一段距离然后旋转180度回到初始位置延时20s,方便关闭电源结束巡游 default :Rotate(UTurnSteps);whereamI; LeftPulse1500;RightPulse1500;break; //每到达一个景点就旋转180度实现掉头whereamI加1即经过了一个景点 }break; default : LeftPulse1500;RightPulse1500;break; } MoveAStep(LeftPulse,RightPulse);//给形参传递不同的值使小车实现不同的运动 } int Get_4QTI_State(void) { return P10xf0;//返回一个十六进制的整形数据以得到小车的状态 } void Forward(int steps)//前进 { int i; for(i0;isteps;i) MoveAStep(1700,1300); } void MoveAStep(int LeftP,int RightP) //给形参传递不同的值使小车实现不同的运动 { P1_11; delay_nus(LeftP); P1_10; P1_01; delay_nus(RightP); P1_00; delay_nms(20); } void RightTurn(int steps) //右转 { int i; for(i0;isteps;i) MoveAStep(1700,1500); } void LeftTurn(int steps)//左转 { int i; for(i0;isteps;i) MoveAStep(1500,1300); } void Rotate(int steps) //掉头 { int i; for(i0;isteps;i) MoveAStep(1700,1700); }