2019a/Member

課題について

下の図のようなコースを各チームで作成し、「ミッション」を遂行するためのロボットを作成せよ。

コース説明

選択したコース

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

コースルート

※赤丸地点で一時停止

ロボットについて

ロボットの全体像

ロボット全体像

ロボットの構造

モーターは左側のタイヤをA、右側のタイヤをCに接続しました。アームを稼働させるモーターはBに接続しました。

モーター位置

工夫した点

ロボットの左側面

上図にあるようにロボット本体を四輪のタイヤに対して真ん中に来るように設置しました。 これによって重心の偏りを無くし、タイヤが旋回時に滑らないようにしました。

光センサーについて

光センサーを2に接続し、光センサーを地面に近くなるようロボットに設置することによって光センサーの数字が明暗の違いによって大きく変動するようにしました。これによって、動きを細かく分けやすいようにしました。

光センサー位置

ライントレースについて

光センサーが48より大きい値を示すとき(白)で右に曲がる
光センサーが45と49の間の値を示すとき(灰色)で左に曲がる
光センサーが44より小さい値を示すとき(黒)で左に旋回する

ライントレース説明の図

このように3つの曲がる動きだけを入力し、大きなカーブを曲がりやすいようにしました。0.3秒以上同じ動きを続けることによって停止のプログラムに移るようにしています。
タイマーリセットのプログラムは黒(光センサーが44以下で左に旋回)の時だけでなく、灰色時(光センサーの値が45以上49以下で左に曲がる)にもあえて置かず、交差点で止まりやすいようにしました。このプログラミングによる直線ライントレースでの停止の誤作動はありませんでした。

交差点の判断

黒が連続する時間をもとに交差点の判断を行うようにした。

交差点の判断

上の画像は少し大げさに表しているが交差点では黒が連続する時間が通常のライントレースに比べて長い。そのため、通常のライントレースで光センサーが黒の上にいるより長く、光センサーが交差点で黒の上にいる時間より短い時間として0.3秒を設定し、交差点上でロボットが止まるようにした。

アームについて

アームを前面に設置するとアームやピンポン玉の影が光センサーに干渉する可能性を考えてアームを背面に設置しました。

ピンポン玉を掴む動作

ピンポン玉をアームでしっかりと掴んで固定するのではなく、ボールの周りをアームで囲うような形にしました。これによってボールを掴むときに多少のズレがあってもボールをアームで確保できるようになります。

コース上でのボール掴み

↓下図のようにピンポン玉をホールドした際に隙間が大きくできるように作られています。↓

ボールの掴み

シュートの動き

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

ピンポン玉を弾く絵

プログラミングについて

#defineについて

光センサーに関する定義

光センサーの数値の定義に関しては状況によってセンサーの反応の具合が異なるため、 プログラムを見てすぐに変えられるよう多くを定義しませんでした。

#define THRESHOLD 42

時間に関する定義

#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  

動きに関する定義

#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);    //後退

サブルーチンの設定

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

Aから出発し、Lまで到達するライントレース

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までのライントレース

 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の値
  }
}

交差点で止まるライントレース

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までのライントレース 

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までのライントレース

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までのライントレース

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までのライントレース

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);    //黒なら左へ旋回
        } 
        
    }
 }

実行するプログラム

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にシュート

}

終了

結果

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

まとめ

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


添付ファイル: file課題2 交差点 止まる.jpg 170件 [詳細] fileロボティクスゼミ ライントレース 説明.jpg 314件 [詳細] filerobot_mission2_paint.jpg 187件 [詳細] filerobot_mission2_motor.jpg 158件 [詳細] filerobot_motor_.jpg 71件 [詳細] fileimage1.jpeg 63件 [詳細] filerobot_hold_mission2.jpg 145件 [詳細] filerobot_mission2_holdball.jpg 59件 [詳細] filerobot_mission2_ballhold.jpg 191件 [詳細] filerobotics_mission2.jpg 61件 [詳細] filerobot_mission2_left.jpg 167件 [詳細] filerobot_all_mission2.jpg 151件 [詳細] filemission2_robot_all.jpg 76件 [詳細] filerobotics_mission2_sensor.jpg 132件 [詳細] filerobotics_mission2_corse2.jpg 194件 [詳細] filerobotics_mission2_corse.jpg 165件 [詳細]

トップ   編集 凍結 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2019-08-04 (日) 01:17:27