工業製造
産業用モノのインターネット | 工業材料 | 機器のメンテナンスと修理 | 産業プログラミング |
home  MfgRobots >> 工業製造 >  >> Manufacturing Technology >> 製造プロセス

ロボットに続く人工知能(AI)ベースのライン

コンポーネントと消耗品

Arduino Nano
× 1
SeeedワイヤレスBluetoothRFトランシーバーマスタースレーブ
× 1
>
Amazon Web ServicesIR赤外線センサーモジュール反射型光電ライト
× 1
Sony Continuous Rotation Servo
× 1
Android4.8ボルトバッテリー
× 1

アプリとオンラインサービス

>
Arduino IDE

このプロジェクトについて

ArduinoベースのPick&Place Robotを開発した後、そのアイデアは、ロボットに続く人工知能AIベースのラインを開発することでした。私の最近のプロジェクトでは、サーボモーターの代わりにある種の赤外線センサーを追加するために必要なものだけを、ロボットに続く単純なラインを開発することは初心者にとっては良かったです。 「アイデアはで私のスキルをテストすることでした 上級 レベル」。

難しい作業でしたが、ある種のオンライン調査が私を大いに助けてくれました。

ロボットに続くAIベースのラインが必要なのはなぜですか?

AI になると これは、世界の環境を変えて人間の生活を効果的にする可能性を秘めた最近のテクノロジーです。ロボットにインテリジェンスを適用して現実の問題を理解し、それに応じて解決することで実現できる夢は、<強い>人工知能 だからみんながそれについて話しているのです。

  • 組立/生産ラインで使用できます。
  • 乗客用ピックアップバス。

私のプロトタイプロボットは少し知性があるかもしれませんが、プロジェクトを AIに移行するためのほんの始まりにすぎません。 そこで、ここでは、人工知能を使ったラインフォローロボットの開発を簡単な言葉で段階的に説明していきます。リソースが不足しているため、ロボットを作成しませんが、何らかの調査を行うことでロボットを作成する方法を十分に説明できます。ArduinoIDEで機能する正確なコードを提供するように努めます。最初のAIロボットを非常に簡単に開発できます。

ここからPatreonで私をサポートできます :http://bit.ly/31NfQ6A

「このビデオの説明で、米国で最も安い料金の装置を見つけることができます。をクリックするだけです。 ビデオ 。 "

それでは、プロジェクト「AIベースのラインフォローロボット!」に行きましょう。

赤外線センサーの使用

<図>

私たち プロジェクトには、図に示すように7つの赤外線センサーが含まれています。

  • PID制御の場合は5
  • 左検出の場合は1
  • 右側の検出用にもう1つ。

5つのPID制御センサーの役割 :これらの5つのセンサーは、それぞれ高または低(1、0)のデジタル出力を生成するために使用されます。

黒い線に対して中央に配置されたセンサーは、そのセンサーのみがHIGH(1)を生成します。そのセンサーから同様に考えられる結果は、次のようになります。-

  • 10000
  • 11000
  • 01000
  • 01100
  • 00100
  • 00110
  • 00010
  • 00011
  • 00001
  • 00000
  • 11111

次に、左右の可能な結果のための他の2つのセンサーがあります

左端のセンサー:アナログ出力が高いまたは低い

左端のセンサー:アナログ出力が高いまたは低い

5つのセンサーの値を保存するには、配列変数を作成します。

  in LFSensor [5] ={1,1,1,1,1};  

左右のセンサーの値を保存するには、整数を使用します

  int farleft_sensor =0;  

私たちが知っているように、左と右のパスを格納するために使用できる5つのセンサーがあり、ロボットがアレイでたどります。だから

  LFSensor [0] =digitalRead(lineFollowSensor0); 
LFSensor [1] =digitalRead(lineFollowSensor1);
LFSensor [2] =digitalRead(lineFollowSensor2);
LFSensor [ 3] =digitalRead(lineFollowSensor3);
LFSensor [4] =digitalRead(lineFollowSensor4);
farRightSensor =analogRead(farRightSensorPin);
farLeftSensor =analogRead(farLeftSensorPin);

迷路左手ルール:

見る 迷路の左側のルールを理解するためのこのビデオ

つまり、 左手の法則 次のように説明できます:

  • 左手を壁に置きます。
  • 歩き始めます
  • すべての交差点で、迷路全体で、左手を左側の壁に触れたままにします。
  • 最終的に、迷路の終わりに到達します。おそらく最短で最も直接的な方法ではありませんが、そこにたどり着きます。

したがって、ここで重要なのは、交差点を特定することです。 、上記のルールに基づいてどのコースを取るかを定義します。具体的には、私たちの種類の2D迷路では、8つの異なるタイプの交差点を見つけることができます(上の最初の画像を参照):

写真を見ると、交差点で可能なアクションは次のとおりです。

<図>

クロス」で "

  • 左に移動、または
  • 右に移動、または
  • まっすぐ進む
  • クロス」で 「左に行く、右に行く、まっすぐに行く

T で ":

  • 左に移動、または
  • 右に移動
  • T で ":左に移動、または右に移動

右のみ ":

  • 右に移動
  • 右のみ ":右に移動

左のみ ":

  • 左に移動
  • 左のみ ":左に移動

まっすぐまたは左」で ":

  • 左に移動、または
  • まっすぐ進む
  • まっすぐまたは左」で ":左に移動、またはまっすぐに移動

ストレートまたはライト」で ":

  • 右に移動、または
  • まっすぐ進む
  • ストレートまたはライト」 ":右に移動、またはまっすぐに移動

行き止まり」で ":

  • 戻る(「Uターン」)
  • 行き止まり」 ":戻る(" Uターン ")

迷路の終わり」で ":

  • 停止
  • 迷路の終わり」で ":停止

ただし、「左手の法則」を適用すると、アクションはそれぞれ1つのオプションに削減されます。

  • 「クロス」で:左に移動
  • 「T」で:左に移動
  • 「右のみ」の場合:右に移動
  • 「左のみ」の場合:左に移動
  • 「まっすぐまたは左」の場合:左に移動
  • 「まっすぐまたは正しい」場合:まっすぐ進む
  • 「行き止まり」の場合:戻る(「Uターン」)
  • 「迷路の終わり」で:停止

私たちは、ほぼ、そこにいる! 「落ち着いて!」

ロボットが「行き止まり」または「迷路の終わり」に到達すると、あいまいな状況が存在しないため、それらを簡単に識別できます(これらのアクションは、ラインフォロワーロボットにすでに実装されています、覚えていますか?)。問題は、たとえば、ラインが「クロス」(1)または「T」(2)である可能性があるため、ロボットが「ライン」を検出した場合です。また、「左または右に曲がる」に達すると、単純な曲がり(オプション3または4)または直進するオプション(5または6)になります。ロボットが交差点のタイプを正確に検出するには、追加の手順を実行する必要があります。ロボットは「余分なインチ」を実行し、次の交差点を確認する必要があります(例として上の2番目の図を参照)。

したがって、フローの観点から、可能なアクションは次のように記述できます。

「デッドエンド」で:

  • 戻る(「Uターン」)
  • 「デッドエンド」で:戻る(「Uターン」)

「LINE」で:

  • 余分なインチを実行します
  • 行がある場合:「クロス」です==>左に移動
  • 行がない場合:「T」です==>左に移動
  • 別の行がある場合:それは「迷路の終わり」==>停止
  • 「LINE」で: 1インチ余分に実行 行がある場合:「クロス」です==>左に移動します行がない場合:「T」です==>左に移動します別の行がある場合:「迷路の終わり」です==>停止

「右折」時:

  • 余分なインチを実行します
  • 線がある場合:それはまっすぐまたは右です==>まっすぐに行きます
  • 行がない場合:右のみ==>右に移動
  • 「右折」時: 1インチ余分に走る 線がある場合:それはまっすぐまたは右です==>まっすぐに行きます線がない場合:それは右のみです==>右に行きます

「左折」時:

  • 余分なインチを実行します
  • 線がある場合:直線または左==>左に移動
  • 行がない場合:左のみ==>左に移動
  • 「左折」時: 1インチ余分に走る 線がある場合:直線または左です==>左に移動します線がない場合:左のみです==>左に移動します

実際、「左折」の場合は、とにかく左折するので、テストをスキップすることができます。説明をわかりやすくするために、より一般的な説明を残しました。実際のコードでは、このテストをスキップします。

このプロジェクトの作成中に発生する可能性のあるいくつかの問題があります。

関連トピック

Arduinoドライバーの問題の解決

見る Arduinoドライバーの問題を解決するためのこのビデオ:


コード

  • Robot_Maze_Solve_2
  • 機能
  • GeneralFunctions。
  • SensorFuntions
  • RobotDefines.h
  • MotorFuntions
Robot_Maze_Solve_2 C / C ++
 / * ------------------------------------------------- --------------------- 7センサースマートロボット-BTを介してプログラム可能なPIDコントローラーを備えた迷路ソルバーとラインフォロワー==>によって開発されたナノマウスロボットに基づく基本的な動きMichael Backus(http://www.akrobotnerd.com/)==> http://samvrit.tk/tutorials/pid-control-arduino-line-follower-robot/?ckattempt=1==>に基づく行フォローパス解決コードについては、PatrickMcCabeへのクレジット。patrickmccabemakes.comにアクセスしてください!! Marcelo Jose Rovai- 2016年4月23日-アクセス:http://mjrobot.org ---------------- -------------------------------------------------- -* /#include  #include "robotDefines.h" String command; String device; // BT Module#include  SoftwareSerial BT1(10、11); // Elピン10es Rx yelピン11es Tx // ----------------------------------- ---------- void setup(){Serial.begin(9600); BT1.begin(9600); pinMode(ledPin、OUTPUT); pinMode(buttonPin、INPUT_PULLUP); //ラインフォローセンサーpinMode(lineFollowSensor0、INPUT); pinMode(lineFollowSensor1、INPUT); pinMode(lineFollowSensor2、INPUT); pinMode(lineFollowSensor3、INPUT); pinMode(lineFollowSensor4、INPUT); //サーボleftServo.attach(5); rightServo.attach(3); BT1.print( "ロボットに送信されるPID定数を確認してください"); Serial.print( "ロボットに送信されるPID定数を確認してください"); BT1.println( '\ n'); while(digitalRead(buttonPin)&&!mode){checkBTcmd(); //コマンドがBTリモコンから受信されているかどうかを確認しますmanualCmd();コマンド=""; } checkPIDvalues();モード=停止;ステータス=0; //最初のパス} void loop(){ledBlink(1); BT1.println( "最初のパスを開始"); Serial.println( "最初のパスを開始"); readLFSsensors(); mazeSolve(); //迷路を解くための最初のパスledBlink(2); BT1.println( "最初のパスの終了"); Serial.println( "最初のパスの終了"); while(digitalRead(buttonPin)&&!mode){checkBTcmd(); //コマンドがBTリモコンから受信されているかどうかを確認しますmanualCmd();コマンド=""; } BT1.println( "2回目のパスの開始"); Serial.println( "2回目のパスの開始"); pathIndex =0;ステータス=0; mazeOptimization(); //迷路をできるだけ速く実行しますledBlink(3); BT1.println( "End 2nd Pass"); Serial.println( "End 2nd Pass"); while(digitalRead(buttonPin)&&!mode){checkBTcmd(); //コマンドがBTリモコンから受信されているかどうかを確認しますmanualCmd();コマンド=""; } mode =STOPPED;ステータス=0; //最初のパスpathIndex =0; pathLength =0;} 
関数 C / C ++
 void mazeSolve(void){while(!status){readLFSsensors();スイッチ(モード){ケースNO_LINE:motorStop(); goAndTurn(左、180); recIntersection( 'B');壊す;ケースCONT_LINE:runExtraInch(); readLFSsensors(); if(mode!=CONT_LINE){goAndTurn(LEFT、90); recIntersection( 'L');} //または、「T」または「Cross」)。どちらの場合も、LEFT else mazeEnd();に移動します。壊す;ケースRIGHT_TURN:runExtraInch(); readLFSsensors(); if(mode ==NO_LINE){goAndTurn(RIGHT、90); recIntersection( 'R');} else recIntersection( 'S');壊す;ケースLEFT_TURN:goAndTurn(LEFT、90); recIntersection( 'L');壊す;ケースFOLLOWING_LINE:followingLine();壊す; }}} // ------------------------------------------------- void recIntersection(char direction){path [pathLength] =direction; //交差点をパス変数に格納します。 pathLength ++; simplePath(); //学習したパスを単純化します。} // ---------------------------------------- ------ void mazeEnd(void){motorStop(); BT1.print( "The End ==> Path:"); for(int i =0; i "); Serial.println(pathLength);ステータス=1; mode =STOPPED;} // ------------------------------------------- --- void followLine(void){// readLFSsensors(); calculatePID(); motorPIDcontrol(); } // ----------------------------------------------- ------------------------------------------- //パスの簡略化。戦略は、//シーケンスxBxに遭遇したときはいつでも、行き止まりを切り取ることによってそれを単純化できるということです。 //例として、LBL-> S、単一のSが行き止まりをバイパスするため// LBL.void simplePath(){//最後から2番目のターンが 'B'の場合にのみパスを単純化if( pathLength <3 || path [pathLength-2]!='B')return; int totalAngle =0; int i; for(i =1; i <=3; i ++){switch(path [pathLength-i]){case'R ':totalAngle + =90;壊す;ケース 'L':totalAngle + =270;壊す;ケース 'B':totalAngle + =180;壊す; }} //角度を0〜360度の数値として取得します。 totalAngle =totalAngle%360; //これらのターンをすべて1つに置き換えます。 switch(totalAngle){ケース0:path [pathLength-3] ='S';壊す;ケース90:path [pathLength-3] ='R';壊す;ケース180:path [pathLength-3] ='B';壊す;ケース270:path [pathLength-3] ='L';壊す; } //パスが2ステップ短くなりました。 pathLength- =2; } // ----------------------------------------------- ----------------------------------------------- void mazeOptimization( void){while(!status){readLFSsensors();スイッチ(モード){ケースFOLLOWING_LINE:followingLine();壊す; case CONT_LINE:if(pathIndex> =pathLength)mazeEnd(); else {mazeTurn(path [pathIndex]); pathIndex ++;} break; case LEFT_TURN:if(pathIndex> =pathLength)mazeEnd(); else {mazeTurn(path [pathIndex]); pathIndex ++;} break; case RIGHT_TURN:if(pathIndex> =pathLength)mazeEnd(); else {mazeTurn(path [pathIndex]); pathIndex ++;} break; }}} // ------------------------------------------------- -------- void mazeTurn(char dir){switch(dir){case'L '://左に曲がるgoAndTurn(LEFT、90);壊す; case'R '://右に曲がるgoAndTurn(RIGHT、90);壊す; case'B '://元に戻すgoAndTurn(RIGHT、800);壊す; case'S '://まっすぐ進むrunExtraInch();壊す; }} 
GeneralFunctions。 C / C ++
 void ledBlink(int times){for(int i =0; i  0){Serial.print( "BTから受信したコマンド==>"); Serial.println(デバイス);コマンド=デバイス;デバイス=""; //変数BT1.flush();をリセットします}} // ---------------------------------------------- -------------------------- void manualCmd(){switch(command [0]){case'g ':mode =FOLLOWING_LINE;壊す;ケース 's':motorStop(); //両方のモーターをオフにします。ケース 'f':motorForward();壊す;ケース 'r':motorTurn(RIGHT、30); motorStop();壊す;ケース 'l':motorTurn(LEFT、30); motorStop();壊す;ケース 'b':motorBackward();壊す;ケース 'p':Kp =command [2];壊す;ケース 'i':Ki =command [2];壊す;ケース 'd':Kd =command [2];壊す; }} // ---------------------------------------------- -------------------------- void sendBTdata(int data)//データをBTに送信{digitalWrite(ledPin、HIGH); BT1.print( "Arduinoからのデータ"); BT1.print(data); BT1.print( "xx"); BT1.println( '\ n'); digitalWrite(ledPin、LOW);} // ---------------------------------------- ---------------- voidcalculatePID(){P =エラー; I =I +エラー; D =エラー-previousError; PIDvalue =(Kp * P)+(Ki * I)+(Kd * D); previousError =error;} // ------------------------------------------- ------------- void checkPIDvalues(){BT1.print( "PID:"); BT1.print(Kp); BT1.print( "-"); BT1.print(Ki); BT1.print( "-"); BT1.println(Kd); Serial.print( "PID:"); Serial.print(Kp); Serial.print( "-"); Serial.print(Ki); Serial.print( "-"); Serial.println(Kd); } // ----------------------------------------------- void testLineFollowSensors(){int LFS0 =digitalRead(lineFollowSensor0); int LFS1 =digitalRead(lineFollowSensor1); int LFS2 =digitalRead(lineFollowSensor2); int LFS3 =digitalRead(lineFollowSensor3); int LFS4 =digitalRead(lineFollowSensor4); Serial.print( "LFS:L 0 1 2 3 4 R ==>"); Serial.print(LFS0); Serial.print( ""); Serial.print(LFS1); Serial.print( ""); Serial.print(LFS2); Serial.print( ""); Serial.print(LFS3); Serial.print( ""); Serial.print(LFS4); Serial.print( "==>"); Serial.print( "P:"); Serial.print(P); Serial.print( "I:"); Serial.print(I); Serial.print( "D:"); Serial.print(D); Serial.print( "PID:"); Serial.println(PIDvalue);} 
SensorFuntions C / C ++
 // ------------------------------------------------- ---------------- / *ラインセンサー値の読み取りセンサーアレイエラー値00 0 0 1 4 0 0 0 1 1 3 0 0 0 1 0 2 0 0 1 1 0 1 0 0 1 0 0 0 0 1 1 0 0 -1 0 1 0 0 0 -2 1 1 0 0 0 -3 1 0 0 0 0 -4 1 1 1 1 10ロボットが実線を検出-交差点または終点かどうかをテストof maze0 0 0 0 0 0ロボットが線を検出しませんでした:ターン180o * / void readLFSsensors(){LFSensor [0] =digitalRead(lineFollowSensor0); LFSensor [1] =digitalRead(lineFollowSensor1); LFSensor [2] =digitalRead(lineFollowSensor2); LFSensor [3] =digitalRead(lineFollowSensor3); LFSensor [4] =digitalRead(lineFollowSensor4); farRightSensor =analogRead(farRightSensorPin); farLeftSensor =analogRead(farLeftSensorPin); if((LFSensor [0] ==1)&&(LFSensor [1] ==1)&&(LFSensor [2] ==1)&&(LFSensor [3] ==1)&&(LFSensor [4] ==1 )){モード=CONT_LINE;エラー=0;} else if((LFSensor [0] ==0)&&(farRightSensor "); Serial.print(farRightSensor); Serial.print( "モード:"); Serial.print(モード); Serial.print( "エラー:"); Serial.println(エラー); } // ----------------------------------------------- ------------ void readLateralSensors(void){} 
RobotDefines.h C / C ++
 int mode =0; #define STOPPED 0#define FOLLOWING_LINE 1#define NO_LINE 2#define CONT_LINE 3#define POS_LINE 4#define RIGHT_TURN 5#define LEFT_TURN 6const int power =250; const int iniMotorPower =250; const int adj =0; float adjTurn =8; int extraInch =200; int adjGoAndTurn =800; const int ledPin =13; const int buttonPin =9; //左側のLFSensorは "0" const int lineFollowSensor0 =12; const int lineFollowSensor1 =18; const int lineFollowSensor2 =17; const int lineFollowSensor3 =16; const int lineFollowSensor4 =19; const int farRightSensorPin =0; //アナログピンA0constint farLeftSensorPin =1; //アナログピンA0constint THRESHOLD =150; int farRightSensor =0; int farLeftSensor =0; int LFSensor [5] ={0、0、0、0、0}; // PID controllerfloat Kp =50; float Ki =0; float Kd =0; float error =0、P =0、I =0、D =0、PIDvalue =0; float previousError =0、previousI =0; #define RIGHT 1#define LEFT -1Servo leftServo; Servo rightServo; // ------------------------------------------------ -//特定の迷路フェーズ2(最適化)の定義と変数unsigned char dir; // path変数は、ロボットがたどったパスを格納します:// 'L'は左// 'R'は右// 'S'はまっすぐ(交差点をまっすぐ進む)// 'B'は戻る(Uターン)charpath [100] =""; unsigned char pathLength =0; // pathintの長さpathIndex =0; unsigned int status =0; //解決=0;リーチエンド=1 
MotorFuntions C / C ++
 void motorStop(){leftServo.writeMicroseconds(1500); rightServo.writeMicroseconds(1500); delay(200);} // ------------------------------------------ --- void motorForward(){leftServo.writeMicroseconds(1500-(power + adj)); rightServo.writeMicroseconds(1500 + power);} // -------------------------------------- ------- void motorBackward(){leftServo.writeMicroseconds(1500 + power); rightServo.writeMicroseconds(1500 --power);} // -------------------------------------- ------- void motorFwTime(unsigned int time){motorForward();遅延(時間); motorStop();} // ----------------------------------------------------------- --void motorBwTime(unsigned int time){motorBackward();遅延(時間); motorStop();} // ----------------------------------------------------------- ----- void motorTurn(int direction、intdegrees){leftServo.writeMicroseconds(1500-(iniMotorPower + adj)* direction); rightServo.writeMicroseconds(1500-iniMotorPower * direction);遅延(round(adjTurn * degrees + 20)); motorStop();} // ----------------------------------------------------------- -------- void motorPIDcontrol(){int leftMotorSpeed =1500-(iniMotorPower + adj)-PIDvalue; int rightMotorSpeed =1500 + iniMotorPower-PIDvalue; //モーター速度は最大PWM値を超えてはなりませんconstraint(leftMotorSpeed、1000、2000);制約(rightMotorSpeed、1000、2000); leftServo.writeMicroseconds(leftMotorSpeed); rightServo.writeMicroseconds(rightMotorSpeed); //Serial.print(PIDvalue); //Serial.print( "==>左、右:"); //Serial.print(leftMotorSpeed); //Serial.print( ""); //Serial.println(rightMotorSpeed);} // -------------------------------------- ------------- void runExtraInch(void){motorPIDcontrol(); delay(extraInch); motorStop();} // ----------------------------------------------------------- -------- void goAndTurn(int direction、intdegrees){motorPIDcontrol(); delay(adjGoAndTurn); motorTurn(方向、度);} 

回路図


製造プロセス

  1. Raspberry Piベースの壁回避ロボット– FabLab NerveCentre
  2. 視覚ベースの障害物回避を備えた移動ロボット
  3. NPEの「芸術的」ロボット
  4. 自動化:ロボットラインの再設計
  5. ボッシュがインダストリー4.0に人工知能を追加
  6. スカラロボットライン拡張
  7. 人工知能はフィクションですか、それとも流行ですか?
  8. 人工知能は、ロボットがタッチでオブジェクトを認識するのに役立ちます
  9. 人工知能ロボット
  10. 人工知能の長所と短所
  11. ビッグデータと人工知能