[[2016a/Member]]

#contents

*はじめに [#db5768ef]

今回の課題は下の図のようなコースを各チームで作成し、ミッションを遂行することである。

#ref(2016a-mission2.png)

なお、今回の私のミッションは

B地点からC地点へ

(B地点 → R右折 → Q直進 → Q直進 →P右折 → S右折 → C地点)

である。([[2016年度前期 課題2:http://yakushi.shinshu-u.ac.jp/robotics/?2016a%2FMission2]]引用)

*ロボットの説明 [#dcc4ff80]

キットに付属していた説明書に載っていたように、光センサを取り付けました。

#ref(robo3.jpg)

なお、より正確な測定が出来るよう、床との距離を縮めるようにしました。

#ref(robo4.jpg)

*プログラム [#h080aa93]

**float型関数プログラム [#i7675aa0]

前回の「電池残量によってモーターの回転速度が遅くなる」ことの対策として([[2016a/Member/ngtrz/Mission1:http://yakushi.shinshu-u.ac.jp/robotics/?2016a%2FMember%2Fngtrz%2FMission1]]参照)、

今回は進みたい距離からタイヤの回転角を計算するfloat型の関数を使ったプログラムを用いました。

 float GetAngle(float d) /* dには進みたい距離が入る */
 {
  const float diameter=5.45;  //タイヤの直径()
  const float pi=3.1415;      //円周率(π)
  float ang =d/(diameter*pi)*360.0;  //角度を計算する
  return ang;                 //角度を返す 
 }

***90°回転 [#w1d6ee16]

右折の場合、90°回転が必要となります。

タイヤとタイヤの長さ(タイヤが描く円の半径r)が10.5僂任△襪里如△海譴鮓気float型の関数を利用してタイヤの辿る円周の長さ( L = 2πrx / 360 ) (x:角度) を求めます。

90°回転する場合のタイヤの辿る円周の長さは

L=d=2×3.1415×10.5×90/360≒16.5

ただし、今回私はタイヤをどちらも動かして右旋回させようとしていて、16.5cmでやると180°回転になってしまうので、半分の8.25cmにすることで90°回転にしました。

これより、90°回転を定義しました。

 #define Ninety  GetAngle(8.25)

***2cm進む [#e3d3987b]
交差点を直進する際、2cm進むこと(線の太さが約2cmであるため)が必要となります。

この場合は普通に

d=2

でできます。

これより、2cm進むことを定義しました。

 #define Two GetAngle(2)

**定義 [#je60c3f9]

先ほどの「90°回転」、「2cm進む」定義を元に、「交差点右折」と「交差点直進」を定義しました。

 #define usetsu RotateMotorEx(OUT_BC,50,Ninety,100,true,false); //交差点右折(モータBとCを50%のスピードで同期させず90度前転)
 #define tyokushin RotateMotorEx(OUT_BC,50,Two,0,true,true); //交差点直進(モータBとCを50%のスピードで同期させて2cm分前転)

さらに、ライントレースに必要なことの定義をしました。

 #define OnRL(b,c) OnFwd(OUT_B,b);OnFwd(OUT_C,c); //タイヤBをb%、タイヤCをc%のスピードでそれぞれ進ませる(+:前進、−:後進)
 #define go_forward OnRL(30,30); //前進
 #define turn_left1 OnRL(15,-15); //左旋回
 #define turn_left0 OnRL(15,0); //左折
 #define turn_right0 OnRL(0,15); //右折
 #define turn_right1 OnRL(-15,15); //右旋回

**ライン上走行・交差点認識サブルーチン [#i41302c1]

私はライントレースをさせる際、光センサが黒線と左側の白い部分の境界上を動くようにしました。


光センサが白い部分にさしかかったら黒線側へ、黒い部分にさしかかったら白い方へ向かうようにカーブさせました。


まずライン上を走行するために黒い線の周囲の明るさをセンサーではかり、しきい値を決定しました。

#ref(Line.png)

実際測ると上図のようになったので、しきい値を44に設定、定義しました。

 #define THRESHOLD 44

その後、±の範囲を調整することによって線上で五段階の明るさを認知するようにさせ、暗い順に左旋回、左折、直進、右折、右旋回を行うようにしました。

なお、交差点認識については、上記の五段階認識のうち「もっとも黒い」時がnMAX回続いたときに交差点と認識するようにしました。

試行錯誤を重ねていった結果、nMAX=160が妥当でしたので定義しました。

 #define nMAX 160

ここでまた前回の反省を踏まえ、サブルーチンを用いました。

 sub Line_toresu() //ライン上走行サブルーチン
 {
   SetSensorLight(S3);
   int n=0; //続けて黒になった回数
     while (n <= nMAX) {
   /* 黒を続けてnMAX回繰り返さなければ通常のライントレースをする */
       if (SENSOR_3 < THRESHOLD-15) {
         turn_left1
         n++; //回数を増やす、交差点認識
       } else {
         if (SENSOR_3 < THRESHOLD-7) {
           turn_left0
         } else if (SENSOR_3 < THRESHOLD+7) {
           go_forward
         } else if (SENSOR_3 < THRESHOLD+15) {
           turn_right0
         } else {
           turn_right1
         }
         n=0; //回数リセット
       }
     }
     Off(OUT_BC); 
     Wait(1000); // 交差点認識したら1秒間止まって
     PlaySound(SOUND_UP); //ピロピロ〜と音を出す
     Wait(2000);
  }

**交差点認識後の行動サブルーチン [#md370fd2]

交差点認識後、「右折」、「直進」の2パターンの動作をしなくてはならないので、次のようにサブルーチンを作りました。

 sub Usetsu() //右折サブルーチン
 { 
  OnFwd(OUT_BC,30);
  Wait(650);
  Off(OUT_BC); //右折後にラインと白い部分の境界にいるようにするための調整
 
  usetsu; //右折
  Off(OUT_B);
  Off(OUT_C);
 }


 sub Tyokushin() //直進サブルーチン
 {
  tyokushin; //直進
  Off(OUT_BC);
 }

**ライントレースプログラム [#nd5fefc0]

急カーブ地点に関しては、できる限り緩めになるようカーブの外側の境界を走るようにしました。

 task main()
 {
  /* ラインの左側境界を進む */
  OnFwd(OUT_BC,50);
  Wait(200);
  Off(OUT_BC); //スタート場所からの前進
  Line_toresu(); //交差点Rまで進む
  Usetsu(); //R右折
  
  OnFwd(OUT_C,50);
  Wait(100);
  Off(OUT_C);
  OnFwd(OUT_B,50);
  Wait(75);
  Off(OUT_B); //先にある急カーブに対処するため、ラインの右側境界へ移動
  
  /* ラインの右側境界を進む */
  Line_toresu(); //交差点Q1まで進む
  Tyokushin(); //Q1直進
  
  OnFwd(OUT_B,50);
  Wait(100);
  Off(OUT_B);
  OnFwd(OUT_C,50);
  Wait(75);
  Off(OUT_C); //先にある急カーブに対処するため、ラインの左側境界へ移動
  
  /* ラインの左側境界を進む */
  Line_toresu(); //交差点Q2まで進む
  Tyokushin(); //Q2直進
  Line_toresu(); //交差点Pまで進む
  Usetsu(); //P右折
  Line_toresu(); //交差点Sまで進む
  Usetsu(); //S右折
  Line_toresu();
  
  OnFwd(OUT_BC,50);
  Wait(500);
  Off(OUT_BC); //ゴール場所へ突っ切る
 }

*ミッション遂行タイム [#ob0165e3]

B地点からC地点まで行くまでにかかった時間は103秒でした。

周りと比べると遅くて、少し残念でした。

*感想・考察 [#r903969b]

ミッション遂行タイムにもあるように、周りと比べるとタイムが遅かったです。

スピードを遅く設定していたこともありますが、左右の動きが激しかったのも要因かと思いました。

もう少し性能のよい動きが出来るようなプログラムを組めればよかったです。

プログラムのコンパクトさについては、前回の反省を踏まえ、サブルーチンを用いたことでよりコンパクトにすることが出来ました。

しかしまだ使えるところもあるとおもうので、次回の課題ではより定義、サブルーチンをもちいてコンパクトにわかりやすいプログラムを組んでいきたいです。
しかしまだ使えるところもあるとおもうので、次回の課題ではより定義、サブルーチンをもちいてコンパクトでわかりやすいプログラムを組んでいきたいです。

また、今回もよりよいプログラムに出来るよう、チームの仲間と協力したり相談し合いながら作業しました。

そして仲間との協調性、仲間の大切さをより強く感じました。

次の課題では2チーム合同になるので、協調性を大事に、そして今回の反省点を改善できるよう努めていきたいです。


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