1.作ったロボット

後ろ

後ろ。青い部分の下に丸いブロックがあることでタイヤを2個にし、小回りが利くようにした。写真に見られるタイヤと丸いブロックの3点でロボットを支える。

正面

正面。手前に進む。センサは進行方向に向かって右側に。四角い枠を動かしてコップを掴む。写真とは反対側に枠を動かしてコップをキャッチ。

横

横。ギアの部分で四角い枠を上げ下げする。

4輪でのS字カーブがなかなか上手くいかなかったので、小回りがより効きやすいように、4輪ではなく2輪にした。前方のタイヤ2つと後ろの丸いブロックの3点で床と接する。 センサはロボットの正面右側に付けた。(写真「正面」) また、四角い枠を動かしてコップを運ぶ。(写真「横」「正面」)

2.書いたプログラム

   #define THRESHOLD 45
   #define HIPOWER 7  //直線用のパワー
   #define LOWPOWER 2  //カーブのパワー
   #define set_power_H SetPower(OUT_AC,HIPOWER);  //パワー強く
   #define set_power_L SetPower(OUT_AC,LOWPOWER);  //パワー弱く
   #define go_forward_H set_power_H;OnFwd(OUT_AC);  //速く直進
   #define go_forward_L set_power_L;OnFwd(OUT_AC);  //遅く直進
   #define turn_left set_power_L;OnFwd(OUT_C);Off(OUT_A);  //左折
   #define left_senkai set_power_L;OnFwd(OUT_C);OnRev(OUT_A);  //左旋回
   #define turn_right set_power_L;OnFwd(OUT_A);Off(OUT_C);  //右折
   #define right_senkai set_power_L;OnFwd(OUT_A);OnRev(OUT_C);  //右旋回
   #define Break Off(OUT_AC);Wait(100);  //小休憩
   #define Cross_right set_power_L;OnFwd(OUT_C);Wait(50);  //交差点を直進(ライン右端トレース時)(交差点検知後)(センサ部分がラインをまたぐ)
   #define Cross_left set_power_L;OnFwd(OUT_A);Wait(50);  //交差点を直進(ライン左端トレース時)(交差点検知後)(センサ部分がラインをまたぐ)
   #define Step 1  //ラインの検知間隔
   sub cross_go_forward_right()    //「交差点直進(ラインの右端をトレース)」明るさ5段階のうち最も暗ければ右旋回。2番目に暗ければ右折。最も明るければ左旋回。2番目に明るければ左折。その中間ならば直進。
   {
   int Online=0;  //右旋回(最も暗い)の回数
   int Cross_count=0;  //交差点を通過した回数
   while(Cross_count < 1) {  //交差点通過後まで
        while(Online < 5) {  //5回連続で右旋回する(最も暗い)まで
           if(SENSOR_2 < THRESHOLD-5) {right_senkai;PlayTone(523,1);Online++;}  //最も暗ければ(=右旋回するとき)Onlineに1を代入
           else if(SENSOR_2 < THRESHOLD-2){turn_right;Online=0;}                 else {if(SENSOR_2 < THRESHOLD+2){go_forward_H;}
                     else if(SENSOR_2 < THRESHOLD+5){turn_left;}
                     else {left_senkai;}  Online=0;  //その他の明るさのときは0を代入(リセット)
                        }
   Wait(Step);  //0.01秒ごとに線を検知                }  //交差点識別完了
   Break;  //小休憩
   Cross_right;  //Onlineが5以上で交差点識別、小休憩の後交差点通過
   Cross_count++;  //Cross_countに1代入、サブルーチン終了
                              }
   }
   sub cross_turn_right_right()    //「交差点右折(ラインの右端をトレース)」明るさ5段階のうち最も暗ければ右旋回。2番目に暗ければ右折。最も明るければ左旋回。2番目に明るければ左折。その中間ならば直進。
   {
   int Online=0;  //右旋回(最も暗い)の回数
   int Cross_count=0;  //交差点を通過した回数
   while(Cross_count < 1) {  //交差点通過後まで
        while(Online < 5) {  //5回連続で右旋回する(最も暗い)まで
           if(SENSOR_2 < THRESHOLD-5) {right_senkai;PlayTone(523,1);Online++;}  //最も暗ければOnlineに1代入、それ以外なら0代入(リセット)
           else if(SENSOR_2 < THRESHOLD-2){turn_right;Online=0;}
                else{if(SENSOR_2 < THRESHOLD+2){go_forward_H;}
                     else if(SENSOR_2 < THRESHOLD+2){turn_left;}
                     else{left_senkai;}  Online=0;
                       }
   Wait(Step);  //0.01秒ごとに線を検知               }  //交差点識別完了
   Break;  //小休憩
   right_senkai;Break;go_forward_L;Wait(45);  //交差点右折(右を向いて小休憩後直進)
   Cross_count++;  //Cross_countに1代入、サブルーチン終了
                             }
   }
   sub cross_turn_left_at_R()    //「Rで交差点左折(交差点通過後ラインの右トレースから左トレースに変更)」明るさ5段階のうち最も暗ければ右旋回。2番目に暗ければ右折。最も明るければ左旋回。2番目に明るければ左折。その中間ならば直進。
   {
   int Online=0;  //右旋回(最も暗い)の回数
   int Cross_count=0;  //交差点を通過した回数
   while(Cross_count < 1) {  //交差点通過後まで
        while(Online < 2) {  //2回連続で右旋回する(最も暗い)まで
           if(SENSOR_2 < THRESHOLD-5) {right_senkai;PlayTone(523,1);Online++;}  //最も暗ければOnlineに1代入、それ以外の時はOnlineに1代入(リセット)
           else if(SENSOR_2 < THRESHOLD-2){turn_right;Online=0;}
                else{if(SENSOR_2 < THRESHOLD+5){go_forward_H;}
                     else if(SENSOR_2 < THRESHOLD+2){turn_left;}
                     else{left_senkai;}  Online=0;
                       }
   Wait(Step);  //0.01秒ごとに線を検知                }  //交差点識別完了
   Break;  //小休憩
   OnRev(OUT_AC);Wait(20);Off(OUT_AC);left_senkai;Wait(100);  //左折(少し後退して止まりその後左を向く)(その時点でセンサはおおよそラインの左側に)
   Cross_count++;  //Cross_countに1代入、サブルーチン終了
                              }
   }
   sub cross_go_forward_left()    //「交差点直進(ラインの左端をトレース)(R~Q間のみ)」明るさ5段階のうち最も暗ければ左旋回。2番目に暗ければ左折。最も明るければ右旋回。2番目に明るければ右折。その中間ならば直進。
   {
   int Online=0;  //左旋回(最も暗い)の回数
   int Cross_count=0;  //交差点を通過した回数
   while(Cross_count < 1) {  //交差点通過後まで
   while(Online < 5) {  //5回連続で左旋回する(最も暗い)まで
           if(SENSOR_2 < THRESHOLD-5) {left_senkai;PlayTone(523,1);Online++;}  //最も暗ければOnlineに1代入、それ以外の時0代入(リセット)
           else if(SENSOR_2 < THRESHOLD-2){turn_left;Online=0;}
                else {if(SENSOR_2 < THRESHOLD+2){go_forward_L;}
                     else if(SENSOR_2 < THRESHOLD+5){turn_right;}
                     else {right_senkai;}  Online=0;
                        }
   Wait(Step);  //0.01秒ごとに線を検知                }  //交差点識別
   Break;  //小休憩
   Cross_left;  //交差点通過
   Cross_count++;  //Cross_countに1代入、サブルーチン終了
                              }
   }
   sub cross_turn_left_at_Q()    //「Q左折(左折後左トレースから右トレースに変更)」明るさ5段階のうち最も暗ければ左旋回。2番目に暗ければ左折。最も明るければ右旋回。2番目に明るければ右折。その中間ならば直進。
   {
   int Online=0;  //左旋回(最も暗い)の回数
   int Cross_count=0;  //交差点を通過した回数
   while(Cross_count < 1) {  //交差点通過後まで
   while(Online < 5) {  //5回連続で左旋回する(最も暗い)まで
           if(SENSOR_2 < THRESHOLD-5) {left_senkai;PlayTone(523,1);Online++;}  //最も暗ければOnlineに1代入、それ以外の時0代入(リセット)
           else if(SENSOR_2 < THRESHOLD-2){turn_left;Online=0;}
                else {if(SENSOR_2 < THRESHOLD+2){go_forward_L;}
                     else if(SENSOR_2 < THRESHOLD+5){turn_right;}
                     else {right_senkai;}  Online=0;
                        }
   Wait(Step);  //0.01秒ごとに線を検知                }  //交差点識別完了
   Break;  //小休憩
   OnRev(OUT_AC);Wait(20);Off(OUT_AC);left_senkai;Wait(100);  //交差点左折(少し後退して止まりその後左を向く)(その時点でセンサはおおよそラインの右側に)
   Cross_count++;  //Cross_countに1代入、サブルーチン終了
                              }
   }
   sub cross_turn_left_right()    //「交差点左折(ラインの右端をトレース)(F左折時のみ)」明るさ5段階のうち最も暗ければ右旋回。2番目に暗ければ右折。最も明るければ左旋回。2番目に明るければ左折。その中間ならば直進。
   {
   int Online=0;  //右旋回(最も暗い)の回数
   int Cross_count=0;  //交差点を通過した回数
   while(Cross_count < 1) {  //交差点通過後まで
        while(Online < 5) {  //5回連続で右旋回する(最も暗い)まで
           if(SENSOR_2 < THRESHOLD-5) {right_senkai;PlayTone(523,1);Online++;}  //最も暗ければOnlineに1代入、それ以外の時0代入(リセット)
           else if(SENSOR_2 < THRESHOLD-2){turn_right;Online=0;}
                else{if(SENSOR_2 < THRESHOLD+5){go_forward_H;}
                     else if(SENSOR_2 < THRESHOLD+2){turn_left;}
                     else{left_senkai;}  Online=0;
                       }
   Wait(Step);  //0.01秒ごとに線を検知                }  //交差点識別完了
   Break;  //小休憩
   OnRev(OUT_AC);Wait(20);left_senkai;Wait(70);  //左折(少し後退して止まりその後左を向く)
   Cross_count++;  //Cross_countに1代入、サブルーチン終了
                              }
   }
   sub s_curve()    //「S字カーブ」明るさ5段階のうち最も暗ければ右旋回。2番目に暗ければ右折。最も明るければ左旋回。2番目に明るければ左折。その中間ならば直進。
   {
      ClearTimer(0);  //タイマーリセット
   while(FastTimer(0)<1000)  //10秒でS字区間通過
   {
   if(SENSOR_2<THRESHOLD-5){right_senkai;}
   else if(SENSOR_2<THRESHOLD-2){turn_right;}
        else if(SENSOR_2<THRESHOLD+2){go_forward_H;}  //小回りの利くロボットを作ったのでやや速いスピードでもトレース可能
        else if(SENSOR_2<THRESHOLD+5){turn_left;}
        else{left_senkai;}
                              }
   }
   task main()
   {
   SetSensor(SENSOR_2,SENSOR_LIGHT);  //センサ2を光センサと定義
   cross_go_forward_right();          //B通過
   cross_turn_right_right();          //C右折
   cross_go_forward_right();          //F通過
   s_curve();          //S字カーブ
   cross_turn_right_right();          //E右折
   cross_turn_left_at_R();          //R左折(左折後センサはラインの左端へ)
   cross_go_forward_left();          //P直進
   cross_turn_left_at_Q();          //Q左折(左折後センサはラインの右端へ)
   cross_go_forward_right();          //S通過
   cross_go_forward_right();          //S通過
   cross_turn_left_right();          //F左折
   cross_turn_right_right();          //C右折
   int Online=0;  //右旋回(最も暗い)の回数
   int Cross_count=0;  //交差点を通過した回数
   while(Cross_count < 1) {  //交差点通過後まで
        while(Online < 2) {  //2回連続で右旋回する(最も暗い)まで
           if(SENSOR_2 < THRESHOLD-5) {right_senkai;PlayTone(523,1);Online++;}  //最も暗ければOnlineに1代入、それ以外の時はOnlineに0代入(リセット)
           else if(SENSOR_2 < THRESHOLD-2){turn_right;Online=0;}
                else {if(SENSOR_2 < THRESHOLD+2){go_forward_H;}
                     else if(SENSOR_2 < THRESHOLD+5){turn_left;}
                     else {left_senkai;}  Online=0;
                        }
   Wait(Step);  //0.01秒ごとに線を検知                }  //Dへの境界線識別完了
   Break;
   OnFwd(OUT_AC);Wait(60);Off(OUT_AC);                       //Dへ侵入(12行前のOnline~から)
   Cross_count++;  //Cross_countに1代入、終了
                              }
         }

3.感想

ロボットの構造上センサをロボットの正面右側に付けたので、ラインの右端はスムーズにトレースできたが、左端をトレースする部分ではスムーズにいかないことも多かった。 コースの構造上、右端トレースから左端トレースへ、左端から右端へとセンサの位置を変える必要があり、その部分に大変苦労した。うまくいくように、微調整を繰り返した。 S字カーブはロボットのタイヤを2輪にしたことで、スムーズに解決できた。 交差点の判定などに音をうまく使うことで、より効率的に進めることができたのではと感じた。


添付ファイル: file20171227_180036039.jpg 184件 [詳細] file20171227_180027716.jpg 175件 [詳細] file20171227_180018882.jpg 169件 [詳細] file20171227_180012179.jpg 38件 [詳細] file20171227_175957464.jpg 108件 [詳細]

トップ   編集 凍結 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2018-02-17 (土) 21:55:32