)
這是一臺能沿著預(yù)設(shè)黑色軌跡自主巡游的機器人它在“深圳”地圖上依次經(jīng)過12個“景點”并在每個景點自動掉頭最終回到起點。項目核心是一塊搭載51單片機的BoeBot小車配合4路QTI灰度傳感器通過狀態(tài)機決策實現(xiàn)路徑跟蹤、路口識別和轉(zhuǎn)向控制。傳感器4路QTI紅外反射式傳感器連接至P1.4~P1.7高四位輸出數(shù)字電平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;//向右轉(zhuǎn)90度所需的循環(huán)次數(shù) int left90Steps33;//向左轉(zhuǎn)90度所需的循環(huán)次數(shù) int UTurnSteps45;//旋轉(zhuǎn)180度所需的循環(huán)次數(shù) int whereamI0;//經(jīng)過的景點數(shù) int crossSteps8,j1,k1; void main(void) { uart_Init(); delay_nms(2000);//延時2s,消除打開開關(guān)對小車的影響 while(1) { Follow_Line(); } } void Follow_Line(void) { int QTIState; int LeftPulse,RightPulse; QTIStateGet_4QTI_State();//獲取小車的狀態(tài) switch(QTIState) { case 0x10 : LeftPulse1700;RightPulse1700;break;//右轉(zhuǎn) 0001 case 0x30 : LeftPulse1700;RightPulse1500;break;//小幅右轉(zhuǎn) 0011 case 0x20 : LeftPulse1550;RightPulse1450;break;//前進 0010 case 0x40 : LeftPulse1550;RightPulse1450;break;//前進 0100 case 0x60 : LeftPulse1550;RightPulse1450;break;//前進 0110 case 0x80 : LeftPulse1300;RightPulse1300;break;//左轉(zhuǎn) 1000 case 0xc0 : LeftPulse1500;RightPulse1300;break;//小幅左轉(zhuǎn) 1100 case 0xe0 : // 1110 if(whereamI8k1) { RightTurn(right90Steps); LeftPulse1500;RightPulse1500;k;break; } //經(jīng)過景點8后到達十字路口非理想狀態(tài)下未檢測到“1111”而是檢測到“1110”為保證準(zhǔn)確也讓其右轉(zhuǎn) else if(whereamI2||whereamI4||whereamI10) { RightTurn(right90Steps); LeftPulse1500;RightPulse1500;break; }//經(jīng)過景點2、4、10后到達丁十字路口非理想狀態(tài)下未檢測到“1111”而是檢測到“1110”為保證準(zhǔn)確也讓其右轉(zhuǎn) else if(whereamI5) { Forward(crossSteps);LeftPulse1500;RightPulse1500;break; }//經(jīng)過景點5后到達十字路口時, 非理想狀態(tài)下未檢測到“1111”而是檢測到“1110”為保證準(zhǔn)確也讓其直行 else { LeftTurn(left90Steps); LeftPulse1500;RightPulse1500;break; } case 0x70: if(whereamI8k1) // 0111 { RightTurn(right90Steps); LeftPulse1500;RightPulse1500;k;break; }//經(jīng)過景點8后到達十字路口時, 非理想狀態(tài)下未檢測到“1111”而 是檢測到“0111”為保證準(zhǔn)確也讓其右轉(zhuǎn) else if(whereamI8k2) { LeftTurn(left90Steps);LeftPulse1500;RightPulse1500;break; }//經(jīng)過景點8后再經(jīng)過一個十字路口到達第二個十字路口時非理想狀態(tài)下未檢測到“1111”而是“0111”為保證準(zhǔn)確也讓其左轉(zhuǎn) else if(whereamI10||whereamI5) { Forward(crossSteps);LeftPulse1500;RightPulse1500;break; }//經(jīng)過景點10后到達第二個丁字路口時使其直行經(jīng)過景點5后非理想狀態(tài)下檢測到“0111”為保證準(zhǔn)確也讓其直行 else { RightTurn(right90Steps);LeftPulse1500;RightPulse1500;break; } case 0xf0 : switch(whereamI) //1111 { case 5:Forward(crossSteps);LeftPulse1500;RightPulse1500;break; //經(jīng)過景點5后到達十字路口時使其直行 case 6: if(j1) { LeftTurn(left90Steps); LeftPulse1500;RightPulse1500;j;break; }//經(jīng)過第6個景點到達第1個十字路口時使其左轉(zhuǎn) else { RightTurn(right90Steps); LeftPulse1500;RightPulse1500;break; }//經(jīng)過第6個景點到達第2個十字路口時使其右轉(zhuǎn) case 8: if(k1) { RightTurn(right90Steps); LeftPulse1500;RightPulse1500;k;break; }//經(jīng)過第8個景點到達第1個十字路口時使其右轉(zhuǎn) else { LeftTurn(left90Steps); LeftPulse1500;RightPulse1500;break; }//經(jīng)過第8個景點到達第2個十字路口時使其左轉(zhuǎn) case 9: case 12 : LeftTurn(left90Steps); LeftPulse1500;RightPulse1500;break; //經(jīng)過第9個或第12個景點后到達十字路口時使其左轉(zhuǎn) default :RightTurn(right90Steps); LeftPulse1500;RightPulse1500;break; }break; case 0x00: switch(whereamI) // 0000 { case 12 :Forward(12);Rotate(40);delay_nms(20000); LeftPulse1500;RightPulse1500;break; //游完所有景點后到達起始點時先直行一段距離然后旋轉(zhuǎn)180度回到初始位置延時20s,方便關(guān)閉電源結(jié)束巡游 default :Rotate(UTurnSteps);whereamI; LeftPulse1500;RightPulse1500;break; //每到達一個景點就旋轉(zhuǎn)180度實現(xiàn)掉頭whereamI加1即經(jīng)過了一個景點 }break; default : LeftPulse1500;RightPulse1500;break; } MoveAStep(LeftPulse,RightPulse);//給形參傳遞不同的值使小車實現(xiàn)不同的運動 } int Get_4QTI_State(void) { return P10xf0;//返回一個十六進制的整形數(shù)據(jù)以得到小車的狀態(tài) } void Forward(int steps)//前進 { int i; for(i0;isteps;i) MoveAStep(1700,1300); } void MoveAStep(int LeftP,int RightP) //給形參傳遞不同的值使小車實現(xiàn)不同的運動 { P1_11; delay_nus(LeftP); P1_10; P1_01; delay_nus(RightP); P1_00; delay_nms(20); } void RightTurn(int steps) //右轉(zhuǎn) { int i; for(i0;isteps;i) MoveAStep(1700,1500); } void LeftTurn(int steps)//左轉(zhuǎn) { int i; for(i0;isteps;i) MoveAStep(1500,1300); } void Rotate(int steps) //掉頭 { int i; for(i0;isteps;i) MoveAStep(1700,1700); }