#contents


*課題3 [#w9db7869]
 課題の内容は、[[2019a/Mission2]]を参照。

**コース [#rebc4c75]
 私たちは、カップからカップに移動させることができないと考え、基本点を最低限獲得できるようにした。

&ref("robo_LI.jpg");


*ロボットの説明 [#ude54ebc]
 今回は、NXTを2つ使うことができる課題であり、2つのNXTを繋げるかどうか選択できた。2つを繋げないとボールを掴むのと上げるのをモータで行う必要があるため、最低4つ必要と私たちは考えたため2つを繋げることにした。

**全体像 [#h624113b]
 前にアームがあり、重心が前に行き過ぎて転倒してはいけないのでアームを除いた部分は、少し後ろ重心になっている。NXT2つをどのようにして本体に搭載させるかが難しかった。横に並べると重心やタイヤの位置が難しくなるため、上に並べることで重心の位置が分かりやすい位置になっている。

&ref("IMG_0424.JPG");

**アーム [#ga78c48d]
 ボールを掴めるように動力を一つで開閉できるように、歯車を利用しようと考えボールを掴んでも落ちないようにするためにアームにストッパーをつけた。アームを上にあげるための動力は、一つだと安定して上がらなかったり、アームが重すぎて動かないことがしばしば見受けられたため、2つを使用し根本的なパワーを上げることにした。

&ref("IMG_0422.JPG");

**光センサー [#z0437839]
 ミッション2の時にタイヤよりも後ろに光センサーを設置してしまって、ライントレースの時に苦戦してしまったので今回のミッションでは成功に持っていくためにタイヤよりも少し前に設置した。

&ref("IMG_0423.JPG");

*プログラムの説明 [#n5868c86]
 今回は、2つのNXTを使うため通信する必要があり、親と子に分ける必要があった。

**親(マスター)側 [#w9e66e5f]

***定義したプログラム [#i994bbb4]
 何回も同じプログラムを書くことは無駄であるため定義した。

 まず、簡単にできるものを定義した。

 #define speed 20    //動力の定義
 #define CONN 1
 #define OnRL(speedR,speedL) OnFwd(OUT_B,speedR);OnFwd(OUT_C,speedL); //省略するための定義
 #define deep_turn_R OnRL(-speed,speed); //右旋回
 #define turn_R OnRL(0,speed);  //右折
 #define straight OnRL(speed.speed); //直進
 #define deep_turn_L OnRL(speed,-speed); //左旋回
 #define turn_L OnRL(speed,0);  //左折
 #define cross_line OnFwd(OUT_BC,40);Wait(400); //交差点を横切る
 #define machi Off(OUT_BC);Wait(1000);  //1秒止まる
 #define meireiA 11
 #define meireiB 12
 #define meireiC 13

***サブルーチン [#lcaf8e32]
 自分たちは、線の左側をトレースするようにした。

 void trace_A(int X){
      SetSensorLight(S1);
      long t0;  //long型のt0を定義
      to=CurrentTick(); //t0は現在の時間である
      while(CurrentTick()-t0<X){ //今からt0になるまで()秒立つまでの間プログラムを続ける
          if(SENSOR_1<30){ //もし光センサーが30以下の値が測定されると
          deep_turn_L;}  //左旋回
          else if(SENSOR_1<40){ //もし光センサーが31から40を測定すると
          turn_L; //左折
          t0=CurrentTick();} //t0を更新する
          else if(SENSOR_1<50){ //もし光センサーで41から50の値が測定されると
          straight; //直進する
          t0=CurrentTick();} //t0を更新する
          else if(SENSOR_1<55){ //もし光センサーが51から55の値を測定すると
          turn_R; //右折
          t0=CurrentTick();} //t0を更新する
          else{ //もし光センサーが56以上を測定すると
     deep_turn_R; //右旋回
          t0=CurrentTick(); //t0を更新する
     }
     }
     deep_turn_R; //右旋回
     Wait(400); //0.4秒続ける
     cross_line; //交差点を直進する
     Off(OUT_BC); //止まる
 }

 通常のライントレースであり、交差点で黒が観測される時間が続くことで停止して、下からの4文で交差点で止まった後に旋回して直進するプログラムになっている。このプログラムを使い最初の場所から使用する。


 void trace_B(int Y){
      SetSensorLight(S1);
      long t0; //long型のt0を定義
      t0=CurrentTick();  //t0は現在の時間である
      while(CurrentTick()-t0<Y){ 
          if(SENSOR_1<30){ //もし光センサーの値が30以下なら
          deep_turn_L; //左旋回
          t0=CurrentTick();}  //t0を更新する
          else if(SENSOR_1<40){ //もし光センサーの値が31から40なら
          turn_L; //左折
          t0=CurrntTick();}   //t0を更新する
          else if(SENSOR_1<50){ //もし光センサーの値が41から50なら
          straight; //直進
          t0=CurrentTick();}  //t0を更新する
          else if(SENSOR_1<55){ //もし光センサーの値が51から55なら
          turn_R; //右折
          t0=CurrentTick();}  //t0を更新する
          else {  //もし光センサーの値が55以上なら
     deep_turn_R; //右旋回
          }
     }
     deep_turn_L; //左旋回
     Wait(200); //0.2秒続ける
 }

 ボールを置いてある部分で停止するために、白が観測されたら止まるときに回転した分を逆回転して正面を向くようなプログラムである。


***メインプログラム [#g6612f5d]

 task main();
 {
     int msg;
     trace_A(300); //ライントレース t0=0.3秒まで
     trace_B(200); //ライントレース t0=0.2秒まで
     SendRemorteNumber(CONN,MAILBOX,meireiA); //命令を送る
     while(true){
     ReceiveRemorteNumber(CONN,MAILBOX,true,msg); //返信を受ける
     if(msg==meireiB){
         deep_turn_L; //左旋回
         Wait(1500); //1.5秒続ける
         Off(OUT_BC); //止まる
         SendRemorteNumber(CONN,MAILBOX1,meireiC); 命令を送る
         }
     }
 }

**子(スレーブ)側 [#c6729478]

***定義したプログラム [#g4c03dd5]
 上と同じように定義した。 

 #define speed15 //パワーの定義
 #define OnE(speed) OnFwd(OUT_B,speedE) 
 #define OnRL(speedR,speedL) OnFwd(OUT_B,speedR);OnFwd(OUT_C,speedL)
 #define arm_up OnRev(OUT_B,24) //アームを上げる
 #define arm_down OnRL(speed,speed) //アームを下げる
 #define arm_open OnE(speed) //アームを開く
 #define arm_close OnE(-speed) //アームを閉じる


***サブルーチン [#habf207b]

 void catch()
 {
     arm_down; //アームを下げる
     Wait(950); //0.95秒続ける
     arm_close; //アームを閉める
     Wait(2000); //2秒続ける
     Off(OUT_B); //止まる
     arm_up; //アームを上げる
     Wait(550); //0.55秒続ける
     Off(OUT_AC); //止まる
 }

 ボールを掴むプログラムである。

 void release()
 {
     arm_open; //アームを開く
     Wait(1200); //1.2秒続ける
     Off(OUT_B); //止まる
 }

 ボールを離すプログラムである。


***メインプログラム [#qde9f348]

 task main()
 {
     int msg;
     while(true){
         ReceiveRemorteNumber(CONN,MAILBOX,true,msg); //命令を受ける
         if(msg==meireiA){
             catch(); //ボールを掴む動き
             SendRemorteNumber(CONN,MAILBOX1,meireiB); //返信を送る
             }
         if(msg==meireiC){ //命令を受ける
             releace(); //ボールを離す動き
             }
     }
 }


*感想 [#b2a9fad5]

 ライントレースの部分では、前回のミッションでの改善点や成功した部分などを利用することでスムーズにライントレースをすることができたと思う。だがライントレースではさほど苦戦することはなかったと感じられたが、ロボットを作る部分である2つを繋げることにより大きくなるためアームや重心の位置などにきをつける必要があった。さらに、カップを掴もうとすると必然的に大きなアームにする必要もあった。通信する必要があり、そのためのプログラムなどお考えるのも時間がかかったりした。でも、作るときなどに協力することができてよかったと思う。細かい動きを調整することは時間がかかることも分かった。


*反省点 [#we18bb24]
 ・根本的に時間が足りなかった。テスト期間が終了した次の日に発表だったので時間を作るのが難しく課題の多くの部分を達成するプログラムを作りきることができず簡単な動きしかできなかった。

 ・ボールをカップに入れるための動き(回転)の試行回数が少なかった。上の部分と被るが、ボールを掴めたり掴めなかったりして一定の動きをすることができずに成功率が高い秒数にするための調整がが不十分である。もう少しトライすることで、カップの上空にアームが達することのできる回転になる確率やボールをしっかりとつかむ確率を上げることができた。

 ・コードをもっと処理することも必要であった。


*感想 [#b2a9fad5]

 ライントレースの部分では、前回のミッションでの改善点や成功した部分などを利用することでスムーズにライントレースをすることができたと思う。だがライントレースではさほど苦戦することはなかったと感じられたが、ロボットを作る部分である2つを繋げることにより大きくなるためアームや重心の位置などにきをつける必要があった。さらに、カップを掴もうとすると必然的に大きなアームにする必要もあった。通信する必要があり、そのためのプログラムなどお考えるのも時間がかかったりした。でも、作るときなどに協力することができてよかったと思う。細かい動きを調整することは時間がかかることも分かった。


トップ   編集 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS