2016b/Member

目次

課題

課題の内容

 テーマとしては「野球ロボット」である。ピッチャー役とバッター役に分かれ、ピッチャーの投げたピンポン玉をバッターが打ち、置かれたいくつかのゴールに入れて得点する。今回私はバッターを担当した。詳しいルールはこちら→http://yakushi.shinshu-u.ac.jp/robotics/?2016b%2FMission3

コース

 課題2で使用したコース上に5つのゴールを置いたものをフィールドとする。実際のコースとゴールの位置、各ゴールに入った時の点数は下図のようである。ピッチャーはAからQへ、バッターはCからBへ移動し、競技を始める。

100,コース

機体

 今回は2つの機体を用いたので、バッターだけでなくピッチャーについても触れる。

ピッチャー

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

バッター

全体

  • 初期の機体は各部固定が弱く分解しやすかったが、補強を重ねて安定した機体になった。
  • 前輪駆動で、「バット」はピッチャーに向き合うとき回転する角度が小さく済むように横向きに取り付けた。

分解性

 各パーツが大きいが、それなりに分解しやすい機体になった。

100,分解

「バット」

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

 

ライトセンサー

 一部ライントレースをするため、ライトセンサーを取り付けた。前回の反省を生かして地面との距離は前より近くした。

100,正面

後輪

 当初はキャスターを採用していたが、思いのほか曲がりにくかった。よって摩擦の少ない別の部品に取り換えた。結果、回転がスムーズになった。

機体についての反省

  • サイズの規定が大きな壁だった。バット部分を横に取り付けることで何とか収まったものの、ギリギリだった。NXT本体の取り付け方などをもっと工夫して、コンパクトにできればよかったと思う。
  • ピッチャーから射出されるピンポン玉の軌道が逸れ気味だったので、バッター側でも鉤爪を横に広くするなどの工夫をするべきだった。

プログラム

通信

 本課題では、2つの機体のBluetoothによる通信が主目的となっていた。ピッチャー、バッター両者のプログラムの通信にかかわる部分で説明を入れていく。Masterはピッチャー、Slaveはバッターである。

ピッチャー

 黒線の数をライトセンサーで数え、角度制御でマウンドまで移動する。投球は重力に従って転がしている。  

#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;
            }
    }
}

 Bluetoothの通信によって、打席に着いたバッターの打撃時のプログラムをピッチャー側から実行している。その後はバッター側から返信された数字次第でピンポン玉を発射するかしないかを決めている。

バッター

「打席」に着くまで

  • 各動作の定義
    #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);       //打席に入った合図
}
  • 最初は超音波センサーを用いてピッチャーとの向きを合わせようと試みたが、誤検知が多かったため、角度制御で合わせることにした。結果かなり正確に向きを合わせることに成功した。

「打席」についてから

  • 各動作の定義
#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);    //2カ所変数にすることで、左右に好きな角度だけ回転できるようにした

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

int x=1;    //打撃の回数カウント用
  • ピッチャーサイドとの通信と打撃  ピッチャー側が親だが、バッターが送った数字によってピンポン玉を発射するかどうか決めているので、実質の親はバッター側と言える。打撃回数カウント用のxを用いて、xの値によって機体の向きを変え、各ゴールを狙うようにしている。
sub BATTING()
{
    SendRemoteNumber(0,MAILBOX1,11);    //ピンポン玉を発射させる
    Wait(1500);
    CATCH;                              //ピンポン玉をキャッチ
    if(x==1){                           //xの値によって機体の向く向きを変える。打撃後、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){                         //5回まで打撃
        BATTING();
    }
    SendRemoteNumber(0,MAILBOX1,12);    //ピンポン玉の発射を止める
}

プログラムについての反省

 バッター担当は、打席に着くまでのプログラミングをする人と打撃のプログラミングをする人で分担して作業をした。効率よく進んだが、お互いのプログラムを十分理解しないままロボコンに臨んだことは反省点と言える。

ロボコン

結果

 3位。全体的に安定した動作ができたので、技術点を多くもらえた。

反省点

  • ピッチャーの玉がまっすぐ飛んでこなかったため、キャッチできず、基礎点がほとんどもらえなかった。
  • 右に回転する際紙が引っかかって角度がずれてしまった。

まとめ

  • これまで学んできた、基本動作、ライントレース、通信をフルに使うなかなか難易度の高い課題だった。実際ロボコンでも完璧に成功したチームはなかった。
  • 私たちのチームは特に最初の移動については安定した動作をすることができた。しかし肝心の打撃がうまくいかなかったのは詰めが甘かった。
  • 超音波センサーを使いこなせなかったことも悔やまれるが、角度制御のみでかなり正確に狙った位置へ着くことができたのはよかった。
  • もう少し時間があれば、ハード、ソフト両面とも改善できたと考えてしまうが、まだまだ先の見通しと問題解決能力が足りなかったゆえの結果として受け止める。
  • 満足とはいえないまでも、これまで学んできたことを活用して、それなりのロボコンができたことをうれしく思う。

「ロボティクス入門ゼミ」を受講しての感想

 ロボットに興味がある、という至極単純な理由で受講した本講義だが、さまざまないい影響を受けることができた。レゴとはいえ説明書なしにロボットを組み立てる難しさ、プログラミングでエラーが返ってきたとき何がおかしいのかを見つける大変さ、コンパイルが通って、思い通りにロボットが動いた時の楽しさ。これらの経験をしたことで、よりロボットそしてプログラミングへの興味が増した。改めて、本講義を受けてよかったと思う。指導してくださった松本先生、ありがとうございました。


添付ファイル: file鉤爪.JPG 86件 [詳細] file分解図.JPG 77件 [詳細] file正面.JPG 69件 [詳細] file課題3コース.JPG 78件 [詳細] fileピッチャー.JPG 64件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2017-02-12 (日) 19:40:49