[[2016b/Member]]

目次
#contents
*課題 [#tae1a51f]
**課題の内容 [#s1254745]
 テーマとしては「野球ロボット」である。ピッチャー役とバッター役に分かれ、ピッチャーの投げたピンポン玉をバッターが打ち、置かれたいくつかのゴールに入れて得点する。今回私はバッターを担当した。詳しいルールはこちら→http://yakushi.shinshu-u.ac.jp/robotics/?2016b%2FMission3
**コース [#h09300fd]
 課題2で使用したコース上に5つのゴールを置いたものをフィールドとする。実際のコースとゴールの位置、各ゴールに入った時の点数は下図のようである。
 課題2で使用したコース上に5つのゴールを置いたものをフィールドとする。実際のコースとゴールの位置、各ゴールに入った時の点数は下図のようである。ピッチャーはAからQへ、バッターはCからBへ移動し、競技を始める。

#ref(2016b/Member/sennokiseki/Mission3/課題3コース.JPG,100,コース)

*機体 [#sa866265]
 今回は2つの機体を用いたので、バッターだけでなくピッチャーについても触れる。
**ピッチャー [#zfe10c03]
-「マウンド」に着くために用いるライトセンサーが付いている。
-ピンポン玉は機体の後ろに装填し、ストッパー部分が回転することで射出され、同時に次弾が落ちてくる。
-最初レールが地面に水平になるよう延長して取り付けられていたが、かえって玉の軌道が逸れてしまったために取り外した。
-問題点としては射出の威力が足りないこと、軌道が逸れやすいこと、玉が2個同時に出てしまう時があることが挙げられる。

#ref(2016b/Member/sennokiseki/Mission3/ピッチャー.JPG,100,ピッチャー)

**バッター [#g5269022]
***分解性 [#d5d0a27c]
 各パーツが大きいが、それなりに分解しやすい機体になった。

#ref(2016b/Member/sennokiseki/Mission3/分解図.JPG,100,分解)

***「バット」 [#q4bfca5e]
-バットとは言うものの、打ち方としては、キャッチ→シュートという感じである。
-鉤爪のような形にすることで、キャッチした後ピンポン玉が転がって抜けないようにしている。爪が上がると、奥に付いた黒い棒がピンポン玉を打ち出す仕組みになっていて、打ち出された球はかなり正確にまっすぐ進む。

#ref(2016b/Member/sennokiseki/Mission3/鉤爪.JPG,100,バット)
 
***ライトセンサー [#k1a2609c]
 一部ライントレースをするため、ライトセンサーを取り付けた。前回の反省を生かして地面との距離は前より近くした。

#ref(2016b/Member/sennokiseki/Mission3/ライトセンサー.JPG,100,ライトセンサー)
#ref(2016b/Member/sennokiseki/Mission3/正面.JPG,100,正面)

***後輪 [#u34fb1c0]
 当初はキャスターを採用していたが、思いのほか曲がりにくかった。よって摩擦の少ない別の部品に取り換えた。
 当初はキャスターを採用していたが、思いのほか曲がりにくかった。よって摩擦の少ない別の部品に取り換えた。結果、回転がスムーズになった。
***機体についての反省 [#j6ddbd08]
-サイズの規定が大きな壁だった。バット部分を横に取り付けることで何とか収まったものの、ギリギリだった。NXT本体の取り付け方などをもっと工夫して、コンパクトにできればよかったと思う。
-ピッチャーから射出されるピンポン玉の軌道がそれ気味だったので、バッター側でも鉤爪を横に広くするなどの工夫をするべきだった。
*プログラム [#a749751d]
**通信 [#xa377af6]
 本課題では、2つの機体のBluetoothによる通信が主目的となっていた。
 本課題では、2つの機体のBluetoothによる通信が主目的となっていた。ピッチャー、バッター両者のプログラムの通信にかかわる部分で説明を入れていく。
**ピッチャー [#n65c9c62]
 黒線の数をライトセンサーで数え、角度制御でマウンドまで移動する。投球は重力に従って転がしている。
 
 #define TURNR(A) RotateMotorEx(OUT_BC,40,A,100,true,true);Wait(1000);
 #define TURNL(L) RotateMotorEx(OUT_BC,40,L,-100,true,true);Wait(1000);
 #define TYOKUSIN OnFwdSync(OUT_BC,40,0);
 #define CM(K) RotateMotorEx(OUT_BC,40,20.47315*K,0,true,true);Wait(1000);
 #define HASSYA RotateMotor(OUT_A,-90,90);Wait(1000);RotateMotor(OUT_A,-90,-90);


 sub BASYO()
 {
     SetSensorLight(S1);
     TYOKUSIN;
     until(SENSOR_1<35);
     Off(OUT_BC);
     Wait(500);
     CM(5);
     Wait(500);
 }


 task main()
 {
     int SIREI;
     TURNR(110);
     CM(36);
     TURNR(150);
     repeat(3){
         BASYO();
     }
     CM(-13);
     TURNR(130);
     until(BluetoothStatus(1)==NO_ERR);
     RemotePlayTone(1,440,1000);
     Wait(1000);
     RemoteStartProgram(1,"DAGEKI.rxe");                //バッター側DAGEKIのプログラムを実行。
     while(SIREI<12){                                   //バッター側から12が送られてくるまでループ
         ReceiveRemoteNumber(MAILBOX1,true,SIREI);      //バッター側からSIREIを受け取る。
             if(SIREI==11){                             //SIREIの数字が11の時ピンポン玉を発射。
                 PlaySound(SOUND_CLICK);
                 Wait(200); 
                 HASSYA;
                 SIREI=0;
             }
     }
 }

**バッター [#s46c0948]
***「打席」に着くまで [#je79e436]
-各動作の定義
 #define go_straight(t)  RotateMotor(OUT_BC,50,t);
 #define go_nonstop      OnFwd(OUT_BC,50);
 #define turn(t)         RotateMotorEx(OUT_BC,60,t,100,true,true);
 #define turn_right      OnFwd(OUT_B,40);
 #define turn_right_slow OnFwd(OUT_B,40); OnRev(OUT_C,30);
 #define turn_left       OnFwd(OUT_C,40);
 #define turn_left_slow  OnFwd(OUT_C,40); OnRev(OUT_B,30);
 #define go_line         OnFwd(OUT_BC,40);
 #define FOLLOW_TIME 5000
 #define SASETSU         OnRev(OUT_BC,50); Wait(400); Off(OUT_BC); OnFwd(OUT_C,50);  Wait(1500); Off(OUT_C);
 
-ライントレースと角度制御
--位置に着くまでの動作は、三つに分かれている。最初は角度制御によってPとBを結ぶ線の近くまで進む。ライトセンサーによって黒線を発見次第、ライントレースの準備に入る。

 sub BEGIN()
 {
     Wait(1500);               //ボタンを押してすぐに動き出さないための猶予の時間
     turn(120);                //最初の位置で回転し、進む方向を定める
     go_straight(1300);        //目的の線付近まで近づく
     PlaySound(SOUND_CLICK);   //接近完了の合図
     go_nonstop;               //黒線発見まで前進
     until(SENSOR_3<=40);      //黒線を発見
     Off(OUT_BC);
     PlaySound(SOUND_CLICK);   //黒線発見の合図
     Wait(1000);
     SASETSU;                  //ライントレースに移行するための方向転換
 }

--続いて五秒間のライントレースに入る。ライントレースの目的は、できる限り正確に「打席」に入ることである。

 sub FOLLOW_LINE()
 {
     long t0=CurrentTick();                         //現在時間を定義
     while(CurrentTick()-t0<FOLLOW_TIME){           //現在時間とスタート時の時間の差が一定未満の時ループ
         if(SENSOR_3<=38){
             turn_right;                            //条件を満たすとき実行(濃黒線)
         }else if(SENSOR_3<=45){
             turn_right_slow;                       //条件を満たすとき実行(薄黒線)
         }else if(SENSOR_3<=50){
             go_line;                               //条件を満たすとき実行(白黒中間)
         }else if(SENSOR_3<=59){
             turn_left_slow;                        //条件を満たすとき実行(白強め)
         }else{
             turn_left;                             //条件を満たすとき実行(完全に白)
         }
     }
     Off(OUT_BC);                                   //B手前で停止
 }

--最後に打席に入ってピッチャーと向かい合うように回転する。

 sub READY()
 {
     go_straight(500);          //Bの中に入る
     OnRev(OUT_BC,50);          //後退する
     until(SENSOR_3<=40);       //黒線検知
     Off(OUT_BC);
     PlaySound(SOUND_CLICK);    //黒線検知の合図
     Wait(1000);
     turn(20);                  //進入角度微調整
     go_straight(400);          //Bの中に入る
     turn(-70);                 //ピッチャーに向き合う
     PlaySound(SOUND_UP);       //打席に入った合図
 }

--最初は超音波センサーを用いてピッチャーとの向きを合わせようと試みたが、誤検知が多かったため、角度制御で合わせることにした。結果かなり正確に向きを合わせることに成功した。

***「打席」についてから [#n04b09a7]
-各動作の定義

 #define CATCH Wait(500);RotateMotor(OUT_A,70,45);Wait(1000);
 #define UTU RotateMotor(OUT_A,-90,45);Wait(1000);
 #define TURN(s,t) RotateMotorEx(OUT_BC,40,s,t,true,true);Wait(1000);

 また、変数xを定義する。

 int x=1;

-ピッチャーサイドとの通信と打撃
**プログラム全体 [#x8715fd2]


 sub BATTING()
 {
     SendRemoteNumber(0,MAILBOX1,11);
     Wait(1500);
     CATCH;
     if(x==1){
         TURN(80,100);
         UTU;
         TURN(80,-100);
         x = x+1;
     } else if(x==2){
         TURN(95,-100);
         UTU;
         TURN(95,100);
         x = x+1;
     } else if(x==3){
         TURN(40,100);
         UTU;
         TURN(40,-100);
         x = x+1;
     } else if(x==4){
         TURN(45,-100);
         UTU;
         TURN(45,100);
         x = x+1;
     } else {
         TURN(45,-100);
         UTU;
         TURN(45,100);
         x = x+1;
     }
 }


 task main()
 {
     UTU;
     while(x<6){
         BATTING();
     }
     SendRemoteNumber(0,MAILBOX1,12);
 }


**プログラムについての反省 [#i5989188]
*ロボコン [#nc024e13]
**結果 [#ibba7e17]
 3位。全体的に安定した動作ができたので、技術点がもらえた。
**反省点 [#nf5502f6]
-ピッチャーの玉がまっすぐ飛んでこなかったため、キャッチできず、基礎点がほとんどもらえなかった。
-右に回転する際紙が引っかかって角度がずれてしまった。
*まとめ [#hcbeadd1]
*「ロボティクス入門ゼミ」を受講しての感想 [#f1e787f6]
 ロボットに興味がある、という至極単純な理由で受講した本講義だが、さまざまないい影響を受けることができた。レゴとはいえ説明書なしにロボットを組み立てる難しさ、プログラミングでエラーが返ってきたとき何がおかしいのかを見つける大変さ、コンパイルが通って、思い通りにロボットが動いた時の楽しさ。これらの経験をしたことで、よりロボットそしてプログラミングへの興味が増した。改めて、本講義を受けてよかったと思う。指導してくださった松本先生、ありがとうございました。



トップ   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS