[[2019a/Member]]
#contents
*課題について [#sf9b88ae]
下の図のようなコースを各チームで作成し、「ミッション」を遂行するためのロボットを作成せよ。
#ref(2019a/Member/Syoshida/Mission2/robotics_mission2_corse2.jpg,100%,コース説明)


**選択したコース [#a8f80e44]
A地点から出発 → M → K(直進) → L(ピンポン玉をつかむ) → K(右折) → J(一時停止の後、左折) → I(直進) → H(直進) → G(左折) → F → E → D(一時停止の後、直進) → C(直進) → B(一時停止) → シュート→ A地点に入る(ゴール)


#ref(2019a/Member/Syoshida/Mission2/robotics_mission2_corse.jpg,100%,コースルート)
※赤丸地点で一時停止


*ロボットについて [#j6ab90ed]
**ロボットの全体像 [#j48e8f12]
#ref(2019a/Member/Syoshida/Mission2/robot_all_mission2.jpg,200%,ロボット全体像)

**ロボットの構造 [#y36b1235]
モーターは左側のタイヤを&color(green){A};、右側のタイヤを&color(red){C};に接続しました。アームを稼働させるモーターは&color(blue){B};に接続しました。
#ref(2019a/Member/Syoshida/Mission2/robot_mission2_motor.jpg,100%,モーター位置)

***工夫した点 [#ubf014a1]
#ref(2019a/Member/Syoshida/Mission2/robot_mission2_left.jpg,100%,ロボットの左側面)
上図にあるようにロボット本体を四輪のタイヤに対して真ん中に来るように設置しました。
これによって重心の偏りを無くし、タイヤが旋回時に滑らないようにしました。
**光センサーについて [#t5d2d4e3]
光センサーを2に接続し、光センサーを地面に近くなるようロボットに設置することによって光センサーの数字が明暗の違いによって大きく変動するようにしました。これによって、動きを細かく分けやすいようにしました。

#ref(2019a/Member/Syoshida/Mission2/robotics_mission2_sensor.jpg,100%,光センサー位置)

***ライントレースについて [#d3d144fb]
光センサーが&color(red,){48より大きい値を示すとき(白)で右に曲がる};~
光センサーが&color(green,){45と49の間の値を示すとき(灰色)で左に曲がる};~
光センサーが&color(blue,){44より小さい値を示すとき(黒)で左に旋回する};
#ref(2019a/Member/Syoshida/Mission2/ロボティクスゼミ ライントレース 説明.jpg,40%,ライントレース説明の図)
このように3つの曲がる動きだけを入力し、大きなカーブを曲がりやすいようにしました。0.3秒以上同じ動きを続けることによって停止のプログラムに移るようにしています。~
タイマーリセットのプログラムは黒(光センサーが44以下で左に旋回)の時だけでなく、灰色時(光センサーの値が45以上49以下で左に曲がる)にもあえて置かず、交差点で止まりやすいようにしました。このプログラミングによる直線ライントレースでの停止の誤作動はありませんでした。~
***交差点の判断 [#p468ae29]
黒が連続する時間をもとに交差点の判断を行うようにした。
#ref(2019a/Member/Syoshida/Mission2/課題2 交差点 止まる.jpg,35%,交差点の判断)
上の画像は少し大げさに表しているが交差点では黒が連続する時間が通常のライントレースに比べて長い。そのため、通常のライントレースで光センサーが黒の上にいるより長く、光センサーが交差点で黒の上にいる時間より短い時間として0.3秒を設定し、交差点上でロボットが止まるようにした。


**アームについて [#dd7253ac]
アームを前面に設置するとアームやピンポン玉の影が光センサーに干渉する可能性を考えてアームを背面に設置しました。
***ピンポン玉を掴む動作 [#k9ca7190]
ピンポン玉をアームでしっかりと掴んで固定するのではなく、ボールの周りをアームで囲うような形にしました。これによってボールを掴むときに多少のズレがあってもボールをアームで確保できるようになります。
#ref(2019a/Member/Syoshida/Mission2/robot_mission2_ballhold.jpg,100%,コース上でのボール掴み)
↓下図のようにピンポン玉をホールドした際に隙間が大きくできるように作られています。↓
#ref(2019a/Member/Syoshida/Mission2/robot_hold_mission2.jpg,170%,ボールの掴み)

***シュートの動き [#p5a9d922]
B地点でアームを展開→ロボットをバック→アームを閉じる→アームをpower(s)を使わずに展開→ピンポン玉を下図で示すように弾く


#ref(2019a/Member/Syoshida/Mission2/robot_mission2_paint.jpg,50%,ピンポン玉を弾く絵)
*プログラミングについて [#o6594a4a]
**#defineについて [#pd1ea27c]
***光センサーに関する定義 [#gd3f1f55]
光センサーの数値の定義に関しては状況によってセンサーの反応の具合が異なるため、
プログラムを見てすぐに変えられるよう多くを定義しませんでした。
 #define THRESHOLD 42
***時間に関する定義 [#r4dd7555]
 #define runtime 1450
 #define runtime1 50
 #define RUN_TIME1 30
 #define RUN_TIME_JIH 170    	
 #define RUN_TIME_HGF 380
 #define RUN_TIME_FE 180
 #define RUN_TIME_DB 1000
 #define STEP 1  
***動きに関する定義 [#w9d4fe29]
 #define turn90 OnFwd(OUT_A);OnRev(OUT_C);Wait(100);Off(OUT_AC);//90度回転
 #define power(s) SetPower(OUT_B,s); //モータのパワーをsにする
 #define turn_left Off(OUT_A); OnFwd(OUT_C);    //左に旋回
 #define turn180 OnFwd(OUT_C);OnRev(OUT_A);Wait(190);Off(OUT_AC);//180度左回転
 #define turn_right OnFwd(OUT_A);OnRev(OUT_C);    //右回転
 #define turn_left90 OnRev(OUT_A);OnFwd(OUT_C);Wait(100);    //左に90度曲がる
 #define go_straight OnFwd(OUT_AC);    //直進
 #define go_back OnRev(OUT_AC);    //後退


**サブルーチンの設定 [#y6cf7c52]
ライントレースをそれぞれの区間ごとに時間内で繰り返すように設定し、細かく分けてあります。

***Aから出発し、Lまで到達するライントレース [#x9e82446]
 sub across_turn()
  {
    SetSensor(SENSOR_2, SENSOR_LIGHT);
 
   ClearTimer(0);
   while (FastTimer(0) <= runtime) {    //14.5秒でAからLまで動き続ける
     if (SENSOR_2 < THRESHOLD){  // 線上なら
      turn_left;                // 左へ
    } else {                    // 線上でなければ
      turn_right;               // 右へ
    }
     Wait(STEP);  // STEPの値
    }
 }
***LからKまでのライントレース [#y61553d5]
  sub across_turn1()
  {
    SetSensor(SENSOR_2, SENSOR_LIGHT);
  
    ClearTimer(0);
    while (FastTimer(0) <= runtime1) {    //0.5秒以上続いたら次のプログラムへ
      if (SENSOR_2 < THRESHOLD){  // 線上なら
        turn_left;                // 左へ
     } else {                    // 線上でなければ
       turn_right;               // 右へ
     }
     Wait(STEP);  // STEPの値
   }
 }

***交差点で止まるライントレース [#q86c29df]
 sub line_trace1()    
    { SetSensor(SENSOR_2,SENSOR_LIGHT);
   
    ClearTimer(0);
 
    while ( FastTimer(0) <= RUN_TIME1 ) {    //0.3秒以上続いたら次の動作へ
        if ( 48 < SENSOR_2 ){
            OnFwd(OUT_A); Off(OUT_C);ClearTimer(0);    //白なら右へ
        } else if (45 <SENSOR_2 < 49) {
            Off(OUT_A); OnFwd(OUT_C);    //灰色なら左へ
        } else {
            OnRev(OUT_A);OnFwd(OUT_C);    //黒なら左へ旋回
         }
         
     }
  
    Off(OUT_AC);Wait(100);    //1秒停止
  }



***JからI、IからHまでのライントレース  [#w6c09603]
 sub line_trace_JIH()    
    { SetSensor(SENSOR_2,SENSOR_LIGHT);
   
    ClearTimer(0);
 
        while ( FastTimer(0) <= RUN_TIME_JIH ) {    //それぞれの区間で1.7秒間動き続ける
            if ( 48 < SENSOR_2 ){
                OnFwd(OUT_A); Off(OUT_C);    //白なら右へ
            } else if (45 <SENSOR_2 < 49) {
                Off(OUT_A); OnFwd(OUT_C);    //灰色なら左へ
            } else {
                OnRev(OUT_A);OnFwd(OUT_C);    //黒なら左へ旋回
             } 
         
        }
    turn_right;Wait(22);OnFwd(OUT_AC);Wait(15);    //交差点で脱線しないよう右へ方向を調整
   }



***HからGを通ってFまでのライントレース [#h166ff30]
 sub line_trace_HGF()   
    { SetSensor(SENSOR_2,SENSOR_LIGHT);
   
    ClearTimer(0);
 
    while ( FastTimer(0) <= RUN_TIME_HGF ) {    //3.8秒間動き続ける
        if ( 48 < SENSOR_2 ){
            OnFwd(OUT_A); Off(OUT_C);    //白なら右へ
        } else if (45 <SENSOR_2 < 49) {
            Off(OUT_A); OnFwd(OUT_C);    //灰色なら左へ
        } else {
            OnRev(OUT_A);OnFwd(OUT_C);    //黒なら左へ旋回
         } 
         
     }
  }


***FからEまでのライントレース [#t98f4375]
 sub line_trace_FE()    
    { SetSensor(SENSOR_2,SENSOR_LIGHT);
   
    ClearTimer(0);
 
    while ( FastTimer(0) <= RUN_TIME_FE ) {    //1.8秒間動き続ける
        if ( 48 < SENSOR_2 ){
            OnFwd(OUT_A); Off(OUT_C);    //白なら右へ
        } else if (45 <SENSOR_2 < 49) {
            Off(OUT_A); OnFwd(OUT_C);    //灰色なら左へ
        } else {
            OnRev(OUT_A);OnFwd(OUT_C);    //黒なら左へ旋回
         } 
         
     }
  }
***DからBまでのライントレース [#id76d7b0]
 sub line_trace_DB()  
    { SetSensor(SENSOR_2,SENSOR_LIGHT);
   
    ClearTimer(0);
 
    while ( FastTimer(0) <= RUN_TIME_DB ) {    //10秒間動き続ける
        if ( 48 < SENSOR_2 ){
            OnFwd(OUT_A); Off(OUT_C);    //白なら右へ
        } else if (45 <SENSOR_2 < 49) {
            Off(OUT_A); OnFwd(OUT_C);    //灰色なら左へ
        } else {
            OnRev(OUT_A);OnFwd(OUT_C);    //黒なら左へ旋回
         } 
         
     }
  }
**実行するプログラム [#nae0eaf0]
AからMを通って出発
 task main(){
     across_turn();    //Aから出発しLに到着
ピンポン玉を掴む動き 
    turn180;
    OnFwd(OUT_B);    //アームを閉じる
    power(0);
    Wait(25);
    Off(OUT_B);
L地点から出発
    across_turn1();    //LからKまでライントレース
K地点到達
    turn90;    //K地点において次に進む方向を向くために回転
    Off(OUT_AC);
    line_trace1();    //kから出発
J地点到達秒、1秒間停止
    line_trace_JIH();    //JからI
I地点到達
    line_trace_JIH();    //IからH
H地点到達
    line_trace_HGF();    //HからF
F地点到達
    turn_left90;    //Fで左90度旋回
    line_trace_FE();    //FからE
E地点到達
    turn_left;    //Eで左旋回(90度以下)
    Wait(30);
    line_trace1();    //EからDまでのライントレース後、一時停止
D地点到達、1秒間停止
    turn_right;Wait(25);    //Dで左へ傾いた分、右に曲がって位置調整
    line_trace_DB();    //DからB
B地点到達
    turn180;    //180度旋回
アーム展開
    OnRev(OUT_B);    
    power(0);
    Wait(25);
    Off(OUT_B);    
    go_straight;    //ボールから離れる
    Wait(100);
    OnFwd(OUT_B);    //アームを閉じる
    power(0);
    Wait(25);
    go_back;    //後ろに下がって位置調整
    Wait(55);
アームでピンポン玉を弾いてAにシュート
    OnFwd(OUT_B);    
    Wait(10);    //ボールをアームで弾いてAにシュート
 
 }
終了

*結果 [#y39b78d2]
シュートをする際にピンポン玉が動いてAに向かって上手くシュートできないこともあった。しかし、ライントレースの動きに関しては正確に、スムーズに動いた。


*まとめ [#k1bf251c]
前回に比べて早くロボットを完成させることができた。動きに関しても課題1の時に比べて滑らかに動いてくれた。急カーブでロボットがラインから逸れて予想と大きく異なる動きをすることがあったがそのたびに問題点を見つけ出し、適切に対処することが出来た。

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