描述
這是一款使用LSRB算法解決迷宮的線迷宮機(jī)器人。與許多機(jī)器人不同,這是通過(guò)使用 IR 傳感器陣列來(lái)完成的,但我找到了一種僅使用 3 個(gè) IR 傳感器來(lái)解決迷宮問(wèn)題的方法。與此同時(shí)還節(jié)省了很多經(jīng)費(fèi),因此這個(gè)項(xiàng)目也可以說(shuō)是愛(ài)好者的一個(gè)簡(jiǎn)單且更便宜的選擇。
前提
在開(kāi)始實(shí)際項(xiàng)目之前,還有一些先決條件。
熟悉通用PCB的焊接
基礎(chǔ)物理(質(zhì)心、摩擦力、重心和車輪)
硬件
對(duì)稱底盤
陀螺儀(可選)
60 RPM 直流電機(jī)
車輪
紅外傳感器
Arduino Pro Mini
1. 對(duì)稱底盤
擁有對(duì)稱底盤非常重要。
如果底盤不對(duì)稱,則機(jī)器人車的質(zhì)心(COM)將不在中心。如果發(fā)生這種情況,機(jī)器人將繼續(xù)向右或向左移動(dòng),這將導(dǎo)致最短路徑算法出現(xiàn)問(wèn)題或缺陷。
2. 馬達(dá)驅(qū)動(dòng)器(L298N)
這將用于驅(qū)動(dòng)直流電機(jī)。L298N是雙通道的,意思是它可以同時(shí)控制兩個(gè)電機(jī)的方向。
3.Mpu 6050
MPU6050是6軸加速度加陀螺儀模塊。這意味著它可以測(cè)量 X、Y 和 Z 方向的加速度,還可以測(cè)量運(yùn)動(dòng)中身體的偏航、俯仰和滾動(dòng)。
4. 60 RPM 直流電機(jī)
這些電機(jī)將用于移動(dòng)機(jī)器人。為什么選擇 60 RPM 電機(jī)?好吧,如果您正在入門,最好從慢速馬達(dá)開(kāi)始。速度慢的機(jī)器人更穩(wěn)定,更容易控制。對(duì)于許多強(qiáng)勁的 RPM,電機(jī)將難以控制(為此您需要強(qiáng)大的 PID 控制器)。因此,要開(kāi)始使用,建議使用 60 RPM 直流電機(jī)。
5. 輪子
這些是迷宮解決機(jī)器人中最重要的組件之一。確保您的車輪具有更好的牽引力并且由優(yōu)質(zhì)橡膠制成。這些車輪將連接到直流電機(jī)。
6. 紅外傳感器
這些傳感器將在檢測(cè)交叉路口類型方面發(fā)揮重要作用。
7.Arduino Pro mini
這將是我們機(jī)器人的大腦。算法的所有處理和計(jì)算都將在這個(gè)微控制器中進(jìn)行。
“LSRB”算法
這是機(jī)器人解決迷宮的算法。在“LSRB”中,L 代表“LEFT”,S 代表“STRAIGHT”,R 代表 RIGHT,B 代表“BACK”或 BACKWARD。這些 LEFT、RIGHT、STRAIGHT 和 BACK 是機(jī)器人遵循的方向。該算法簡(jiǎn)單直接。在該算法中,向左方向具有最高優(yōu)先級(jí),而后(U 形轉(zhuǎn)彎)方向具有最低優(yōu)先級(jí)。讓我們看看這個(gè)算法是什么樣子的:
第 1 步:只要有可能轉(zhuǎn)彎,請(qǐng)始終跟隨左轉(zhuǎn)
第 2 步:如果無(wú)法向左走,請(qǐng)直接走。
第 3 步:如果 LEFT 和 STRAIGHT 都不可能,請(qǐng)選擇 RIGHT。
第 4 步:如果 LEFT、STRAIGHT 和 RIGHT 都不可能返回(或者這意味著要掉頭)
這意味著無(wú)論何時(shí)機(jī)器人在轉(zhuǎn)折點(diǎn)或十字路口,它總是盡可能向左走。如果 LEFT 不可能,那么 STRAIGHT,如果兩者都不可能,那么 RIGHT。如果所有三個(gè)轉(zhuǎn)彎都不可能,那么只能返回。這是您唯一需要了解的 LSRB 算法。基于此,有 8 種可能的情況:
1.Simple 或 Straight lane :這里 LEFT 是不可能的,但 STRAIGHT 路徑是。所以機(jī)器人將遵循直線路徑。
2.左轉(zhuǎn)(僅限左):顧名思義,這是左轉(zhuǎn),所以這里可以左轉(zhuǎn)。根據(jù) LSRB 算法,機(jī)器人應(yīng)盡可能向左走。所以機(jī)器人會(huì)在這里左轉(zhuǎn)。
3.右轉(zhuǎn)(僅右轉(zhuǎn)):同樣顧名思義,這是一個(gè)右轉(zhuǎn),所以左和直路徑都是不可能的,所以根據(jù) LSRB 算法機(jī)器人將右轉(zhuǎn)。
4. T相交(T):這個(gè)相交的形狀像T,所以叫T相交。如圖所示,Robot 可以左轉(zhuǎn)。所以通過(guò)算法機(jī)器人會(huì)左轉(zhuǎn)。
5. 左 T 路口(直或左):再次通過(guò)圖像,我們可以看到機(jī)器人可以走左路,所以機(jī)器人會(huì)在這里左轉(zhuǎn)。
6.Right T 交點(diǎn)(直或右):這里不可能向左,但直路徑是。所以機(jī)器人會(huì)左轉(zhuǎn)
7.Dead End:這里 LEFT、STRAIGHT 和 RIGHT 這三個(gè)都不可能。所以機(jī)器人會(huì)在這里掉頭。
8. 四車道交叉口(Cross):此處再次通過(guò)圖像左轉(zhuǎn)是可能的,因此機(jī)器人將在此處左轉(zhuǎn)。
最后,迷宮結(jié)束:迷宮在這里結(jié)束,所以機(jī)器人會(huì)停在這里。
現(xiàn)在讓我們看一下如何將其轉(zhuǎn)換為代碼:
//LSRB ALGORITHM
IR1 =
IR2 =
IR3 =
void setup?
{
? DECLARE IR1 IR2 AND IR3 AS INPUTS
}
void loop?
{
? IR1 = digitalRead(
? IR2 = digitalRead(
? IR3 = digitalRead(
? if (IR1 == LOW && IR2 == HIGH && IR3 == LOW)//Straight path
? ? {
? ? ?Forward();
? ? }
? if (IR1 == HIGH && IR2 == LOW && IR3 == LOW)//Left turn
? ? {
? ? ?Left();
? ? }
? if (IR1 == LOW && IR2 == LOW && IR3 == HIGH)//Right Turn
? ? {
? ? ? Right();
? ? }
? if (IR1 == HIGH && IR2 == LOW && IR3 == HIGH)//T Intersection
? ? {
? ? ? Left(); // As left is possible
? ? }
? if (IR1 == HIGH && IR2 == HIGH && IR3 == LOW)//Left T Intersection
? ? {
? ? ? Left();// As Left is possible
? ? }
? if (IR1 == LOW && IR2 == HIGH && IR3 == HIGH)//Right T Tntersection
? ? {
? ? ?Forward();//As Straight path is possible
? ? }
? if (IR1 == LOW && IR2 ==LOW && IR3 == LOW)//Dead End
? ? {
? ? ?U_Turn(); //As no other direction is possible
? ? }
? if (IR1 == HIGH && IR2 == HIGH && IR3 == HIGH)//4 Lane intersection
? ? {
? ? ?Left(); //As no other direction is possible
? ? }
? if (IR1 == HIGH && IR2 == HIGH && IR3 == HIGH)//End of Maze
? ? {
? ? ?Stop(); //As no other direction is possible
? ? }?
}
代碼很簡(jiǎn)單,但還有一個(gè)問(wèn)題。4車道交叉口和迷宮盡頭的情況似乎相似。我們的機(jī)器人如何區(qū)分 4 車道交叉口和 End of Maze?答案也很簡(jiǎn)單。讓機(jī)器人走得更遠(yuǎn)一點(diǎn)。現(xiàn)在,如果傳感器的值保持不變,那就結(jié)束了。但是如果左右傳感器的值發(fā)生變化,那么它是一個(gè) 4 路交叉點(diǎn)。讓我們看一下它的代碼:
if (IR1 == HIGH && IR2 == HIGH && IR3 == HIGH)
? ? {
? ? ?Forward();
? ? ?delay(
? ? ?if (IR1 == HIGH && IR2 == HIGH && IR3 == HIGH)
? ? ? ? {
? ? ? ? ? Serial.println("?ND OF MAZE");
? ? ? ? ? Stop();
? ? ? ? }
? ? ?else
? ? ? ? {
? ? ? ? ?Serial.println("FOUR WAY INTERSECTION");
? ? ? ? ?Left();
? ? ? ? }
? ? }
最短路徑算法
這是機(jī)器人用來(lái)計(jì)算迷宮中最短路徑的算法。它使用使用 LSRB 算法獲取的路徑并將其轉(zhuǎn)換為最短路徑。如何?讓我們看看這是如何工作的。考慮下圖中的迷宮。現(xiàn)在讓我們?cè)谶@里放置一個(gè)機(jī)器人,讓我們通過(guò) LSRB 算法可視化它的路徑。我們可以通過(guò)使用 LSRB 算法,機(jī)器人將采取 LEFT、LEFT、BACK、RIGHT、STRAIGHT。簡(jiǎn)而言之,我們可以說(shuō)機(jī)器人跟隨 L、L、B、R、S。現(xiàn)在作為一個(gè)人,我們可以直接說(shuō)最短路徑就是這里的 RIGHT 或“R”轉(zhuǎn)。但是機(jī)器人是如何做到這一點(diǎn)的呢?最短路徑算法在這里使用了替換。這些替換如下所示:
LBR = “B”
LBS = “R”
RBL = “B”
SBL = “R”
SBS = “B”
LBL = “S”
現(xiàn)在讓我們通過(guò)替換方法縮短路徑。在路徑 {L, L, B, R, S} 中,LBR = 'B' 所以 Path 現(xiàn)在變?yōu)?{ L, B, S}。現(xiàn)在 LBS = 'R' 所以最終路徑變?yōu)?{ R} ,如前所述,這是正確的。現(xiàn)在讓我們將這個(gè)算法轉(zhuǎn)化為 Arduino 代碼:
void CALCULATE_SHORTEST_PATH(char MAZE_ARRAY[], int SIZE_OF_ARRAY)
{
? /*ONCE THE ROBOT COMPLETES THE MAZE THE FINAL SHORTEST PATH CALCULATED
? IS STORED IN THE ROBOT MEMORY.THIS SHORTEST PATH IS USED TO COMPLETE
? THE SAME MAZE IN SHORTEST AMOUNT OF TIME.(L :LEFT, R:RIGHT, B:BACK,S:STRAIGHT)
? BELOW ARE THE FEW SUBSTITUTIONS TO CONVERT FULL MAZE PATH TO ITS?
? SHORTEST PATH:
? LBL = S
? LBR = B
? LBS = R
? RBL = B
? SBL = R
? SBS = B
? LBL = S */
? char ACTION;
??
? for(int i = 0; i <= SIZE_OF_ARRAY-2; i++)
? ? {
? ? ? ACTION = MAZE_ARRAY[i];
? ? ? ? ? ?
? ? ? if(ACTION == 'B')
? ? ? ? {
? ? ? ? ? if(MAZE_ARRAY[i-1]== 'L' && MAZE_ARRAY[i+1] == 'R')
? ? ? ? ? ? {
? ? ? ? ? ? ? MAZE_ARRAY[i] = 'B';
? ? ? ? ? ? ? MAZE_ARRAY[i-1] = 0;
? ? ? ? ? ? ? MAZE_ARRAY[i+1] = 0;
? ? ? ? ? ? ? REARRANGE(MAZE_ARRAY,SIZE_OF_ARRAY,i-1,i,i+1);?
? ? ? ? ? ? }
? ? ? ? ? ?if(MAZE_ARRAY[i-1]== 'L' && MAZE_ARRAY[i+1] == 'S')
? ? ? ? ? ? {
? ? ? ? ? ? ? MAZE_ARRAY[i] = 'R';
? ? ? ? ? ? ? MAZE_ARRAY[i-1] = 0;
? ? ? ? ? ? ? MAZE_ARRAY[i+1] = 0;
? ? ? ? ? ? ? REARRANGE(MAZE_ARRAY,SIZE_OF_ARRAY,i-1,i,i+1);
? ? ? ? ? ? }
? ? ? ? ? ? if(MAZE_ARRAY[i-1]== 'R' && MAZE_ARRAY[i+1] == 'L')
? ? ? ? ? ? {
? ? ? ? ? ? ? MAZE_ARRAY[i] = 'B';
? ? ? ? ? ? ? MAZE_ARRAY[i-1] = 0;
? ? ? ? ? ? ? MAZE_ARRAY[i+1] = 0;
? ? ? ? ? ? ? REARRANGE(MAZE_ARRAY,SIZE_OF_ARRAY,i-1,i,i+1); ? ? ? ??
? ? ? ? ? ? }
? ? ? ? ? ? if(MAZE_ARRAY[i-1]== 'S' && MAZE_ARRAY[i+1] == 'L')
? ? ? ? ? ? {
? ? ? ? ? ? ? MAZE_ARRAY[i] = 'R';
? ? ? ? ? ? ? MAZE_ARRAY[i-1] = 0;
? ? ? ? ? ? ? MAZE_ARRAY[i+1] = 0;
? ? ? ? ? ? ? REARRANGE(MAZE_ARRAY,SIZE_OF_ARRAY,i-1,i,i+1); ? ? ? ? ? ??
? ? ? ? ? ? }
? ? ? ? ? ? if(MAZE_ARRAY[i-1]== 'S' && MAZE_ARRAY[i+1] == 'S')
? ? ? ? ? ? {
? ? ? ? ? ? ? MAZE_ARRAY[i] = 'B';
? ? ? ? ? ? ? MAZE_ARRAY[i-1] = 0;
? ? ? ? ? ? ? MAZE_ARRAY[i+1] = 0;
? ? ? ? ? ? ? REARRANGE(MAZE_ARRAY,SIZE_OF_ARRAY,i-1,i,i+1); ? ? ? ? ? ??
? ? ? ? ? ? }
? ? ? ? ? ? if(MAZE_ARRAY[i-1]== 'L' && MAZE_ARRAY[i+1] == 'L')
? ? ? ? ? ? {
? ? ? ? ? ? ? MAZE_ARRAY[i] = 'S';
? ? ? ? ? ? ? MAZE_ARRAY[i-1] = 0;
? ? ? ? ? ? ? MAZE_ARRAY[i+1] = 0;
? ? ? ? ? ? ? REARRANGE(MAZE_ARRAY,SIZE_OF_ARRAY,i-1,i,i+1);
? ? ? ? ? ? }
? ? ? ? ? ??
? ? ? ? ? i = -1;
? ? ? ? }
? ? ? ?
? ? ? ?delay(100); ??
? ? }
}
最短路徑算法可以用 3 個(gè)紅外傳感器嗎?
如果您只使用 3 個(gè)紅外傳感器,那就很難了。為了使其工作,您必須使用 PID 算法使機(jī)器人遵循絕對(duì)直線路徑。如果您的機(jī)器人遵循絕對(duì)直線路徑,則只能在其中實(shí)現(xiàn)最短路徑算法。
PID控制器
PID控制器中的PID代表比例積分和微分。這將在我們的機(jī)器人中用于遵循一條完全筆直的路徑。先查看一下PID這個(gè)術(shù)語(yǔ)的意思:
1.Proportional:此項(xiàng)與誤差(E)項(xiàng)成正比。誤差越大,比例部分的值越大。該值負(fù)責(zé)機(jī)器人的轉(zhuǎn)動(dòng)。例如,如果誤差很大,那么機(jī)器人的動(dòng)作也會(huì)很強(qiáng)。所以基本上比例負(fù)責(zé)機(jī)器人的動(dòng)作強(qiáng)度。比例的缺點(diǎn)是它會(huì)產(chǎn)生很多振蕩。就像如果機(jī)器人只包含比例部分,那么車輛將繼續(xù)從左到右擺動(dòng)。好吧,它會(huì)直走,但會(huì)振蕩很多。通過(guò)比例控制獲得的增益用“KP”表示。
P = KP x Error
2. 積分:即使在微分部分消除了振蕩之后,仍然存在小的偏移量。積分部分通過(guò)考慮所有誤差來(lái)消除此偏移。積分項(xiàng)隨時(shí)間增加。通過(guò)積分獲得的增益用“KI”表示。
I = I + KI x Error
3 微分:微分項(xiàng)減少或消除了比例項(xiàng)產(chǎn)生的振蕩。這將使機(jī)器人的運(yùn)動(dòng)更加順暢。機(jī)器人將沿著一條直線前進(jìn),沒(méi)有振蕩。Derivative 獲得的增益用“KD”表示。
D = KD x (Error - Previous_Error)/Time
PID 的公式由下式給出:
所以最終的PID值是通過(guò)將這些項(xiàng)相加得到的:
PID = P + I + D
PID 的主要目標(biāo)是盡可能減少誤差項(xiàng)。在繼續(xù)編碼之前,PID 控制器需要三個(gè)主要元素。
1. 反饋:反饋是一個(gè)過(guò)程,其中一部分輸出用作迭代中的輸入。在我們的案例中,反饋是由 MPU6050 提供的。我們得到了什么樣的反饋?我們得到陀螺值作為反饋。
2.Actuator:這個(gè)東西起到改變系統(tǒng)輸出的作用。它可以是伺服電機(jī)、直流電機(jī)或任何其他電機(jī)。在我們的例子中,執(zhí)行器是機(jī)器人的兩個(gè)直流電機(jī)。
3.SetPoint :這是我們想要達(dá)到的理想點(diǎn)或值。它是通過(guò)完全消除誤差而獲得的。
現(xiàn)在將這個(gè)理論轉(zhuǎn)化為代碼:
double PID_CONTROLLER(double FEEDBACK, double dt)
{
? double ERROR_VALUE;
? double PREVIOUS_ERROR_VALUE = 0;
? double SETPOINT =
? double KP =
? double KI =
? double KD =
? double P;
? double I;
? double D;
? double INTEGRAL;
? double DERIVATIVE;
? double OUTPUT_VALUE;
? ERROR_VALUE = SETPOINT - FEEDBACK; //Here the feedback is YAW from MPU6050
? P = KP*ERROR_VALUE;?
? INTEGRAL += ERROR_VALUE*dt;
? I = KI*INTEGRAL;
? DERIVATIVE += (ERROR_VALUE-PREVIOUS_ERROR_VALUE)/dt;
? D = KD*DERIVATIVE;
? OUTPUT_VALUE = P + I + D ;
? PREVIOUS_ERROR_VALUE = ERROR_VALUE;
? return OUTPUT_VALUE;
??
}
PID值的調(diào)整:
調(diào)整系統(tǒng)的 Kp、Ki 和 Kd 值的方法有很多,其中一種是手動(dòng)調(diào)整,通過(guò)它可以輕松實(shí)現(xiàn)穩(wěn)定性。最初,Kp、Ki 和 Kd 值設(shè)置為零。然后 Kp 值從零增加到系統(tǒng)開(kāi)始從其平均位置振蕩的點(diǎn)。
隨著 Kp 值的增加,可以看出系統(tǒng)的響應(yīng)逐漸增加。保持 Kp 值恒定,然后增加 Ki 值,直到從系統(tǒng)中可以看出,朝某個(gè)方向的小傾斜傾向于使車輛朝該方向加速。當(dāng)正確獲得 Kp 和 Ki 值時(shí),則增加 Kd 值。Kd 值增加,從而顯著降低了快速加速度。
適當(dāng)?shù)?KD 值會(huì)導(dǎo)致較小的過(guò)沖和振蕩。在獲得粗略的 Kp、Ki 和 Kd 值后,進(jìn)行微調(diào)。以上步驟重復(fù)多次,得到增益值的最佳組合。
PID控制器
即使使用對(duì)稱的底盤,您可能已經(jīng)注意到機(jī)器人在沿線行駛時(shí)仍然會(huì)向左或向右移動(dòng),這是因?yàn)橹绷麟姍C(jī)。愛(ài)好者使用的直流電機(jī)并不完美。沒(méi)有兩個(gè)電機(jī)是一樣的。它們的機(jī)械結(jié)構(gòu)之間總是存在細(xì)微差別。如果您的機(jī)器人遵循絕對(duì)直線路徑,那么您很幸運(yùn),恭喜!但很多時(shí)候這種情況不會(huì)發(fā)生,機(jī)器人通常不會(huì)向左或向右移動(dòng)。如果您不使用紅外傳感器陣列,這可能會(huì)影響您的最短路徑算法。對(duì) PID 的另一種需求是當(dāng)您使用非常高的 RPM 電機(jī)時(shí)。
為了克服這個(gè)問(wèn)題,有很多選擇:
1.使用優(yōu)質(zhì)直流電機(jī)(不保證直線路徑)
2.使用優(yōu)質(zhì)車輪(不保證直線路徑)
3.使用高度機(jī)械精確的底盤(不保證直線路徑)
4.降低一個(gè)電機(jī)的速度,使兩個(gè)電機(jī)的速度完美匹配(但這樣做后仍然存在微小的誤差,使機(jī)器人幾乎沒(méi)有偏離軌道)。
5.使用旋轉(zhuǎn)編碼器(有時(shí)可能很好用)
6.使用PID控制器(如果編碼完美,保證機(jī)器人的直線路徑)。
在所有這些選項(xiàng)中,只有 PID 控制器可以保證機(jī)器人的絕對(duì)直線路徑。
構(gòu)造
機(jī)器人的構(gòu)造非常簡(jiǎn)單。我很確定只有圖像就足以讓您構(gòu)建硬件,所以我只提供圖像。
最終成果
請(qǐng)注意,代碼將僅是 LSRB 算法的實(shí)現(xiàn)。代碼中有一個(gè)最短路徑函數(shù),您可以使用它來(lái)實(shí)現(xiàn)最短路徑算法。您可以嘗試使用該功能來(lái)實(shí)現(xiàn) 3 個(gè)紅外傳感器的最短路徑。
評(píng)論