- 追加された行はこの色です。
- 削除された行はこの色です。
#author("2020-01-30T14:31:53+09:00","Nakakoo","Nakakoo")
#author("2020-02-02T12:22:22+09:00","Nakakoo","Nakakoo")
目次
#contents
*課題2 [#cef1aa34]
#ref(./2019b-mission2s.jpg,100%,コースの画像)
今回の課題の内容は、A地点を出発しいずれかのコースを黒線に沿って動きボールを捕まえるというものである。
~僕が選んだのは一番のコースである。
~1.A地点から出発→C (直進)→D (一時停止の後、直進)→F 通過→G (一時停止の後、左折)→H (一時停止の後、左折)→I (ボールをつかんでUターン)
~→H (直進)→J (一時停止)→A地点に入る(ゴール)
*ロボットについて [#z1bdc5bc]
**ロボットの全体像 [#cbbdd0ca]
#ref(./IMG_5980s.JPG,50%,車体の画像)
上のようなロボットをつくった。基本構造は説明書と同じ機体にした。
~改善すべき点としては、もっと光センサーとタイヤとの距離を短くするべきだった点だ。
上のようなロボットをつくった。基本構造は説明書と同じであり、ボールを捕まえる機構を上に乗せただけである。
改善すべき点としては、もっと光センサーとタイヤとの距離を短くするべきだった点だ。タイヤとセンサーの位置が遠いと
ラインを識別する位置とタイヤが曲がる位置にずれが生じてしまい、ライントレースが上手くいかないことがあった。
例えば急なカーブを交差点と勘違いしてしまい、カーブの途中でとまってしまうこともあった。過去のレポートを参考にして
多少時間がかかっても光センサーの位置を直したほうがよかったと感じた。
**ボールをつかむ機構 [#p9750222]
#ref(./IMG_5981s.JPG,50%,機構の画像)
ボールをつかむ機構は上のようにした。アームはボールを確実につかめるようにかなり大きめにした。
~工夫した点は、車体の重心を移動させないようにシンプルな構造にしたことと、カーブしたときにボールに当たらないようにパーツを少なくしたことだ。
工夫した点は、車体の重心を移動させないようにできるだけ軽くしたことと、カーブしたときにボールに当たらないようにパーツを少なくし、シンプルな構造にしたことだ。
反省点は、ボールを見つける超音波センサーを使えなかったことだ。ライントレースのプログラムにどうしても超音波センサーを取り入れることができず、
自力でボールの手前まで車体を動かすしかなかった。次回の課題では今回の反省を生かし、
センサーを使ってモノを見つけるプログラムを描けるようにしたい。
*プログラミングについて [#o74f1701]
**ライントレース [#w8f3e901]
黒い線に沿って動かすためにライントレースというプログラムを作る。ライントレースのプログラムは光センサーを用いて、
~「完全な黒」、「黒よりの灰色」、「灰色」、「白よりの灰色」、「完全な白」の5つの段階の明るさを判別して、それぞれの明るさで別々の動きをさせる。
~5つの測定した値は以下のものである。
#ref(./スライド1.JPG,50%,ラインの画像)
それぞれの値の時の動作のプログラムは次のように定義した。
#define SPEED 35
#define speed 25
#define mae OnFwd(OUT_BC,SPEED); //前に進む
#define migi1 OnFwd(OUT_C,SPEED);Off(OUT_B); //右に曲がる
#define migi2 OnFwd(OUT_C,speed);OnRev(OUT_B,SPEED); //右に旋回
#define hidari1 OnFwd(OUT_B,SPEED);Off(OUT_C); //左に曲がる
#define hidari2 OnFwd(OUT_B,speed);OnRev(OUT_C,SPEED); //左に旋回
#define u_turn OnRev(OUT_B,SPEED);OnFwd(OUT_C,SPEED);Wait(1000);Off(OUT_BC); //Uターンする
#define ball OnFwd(OUT_A,SPEED);Wait(500);Off(OUT_A); //ボールを掴む
スムーズにライントレースができるように、五段階に分けた。
**線の左を走るプログラム [#o9d90d43]
sub line_follow1()
{
SetSensorLight(S4);
long t0;
t0=CurrentTick();
while(CurrentTick()-t0<110){ //0.11秒未満の間
if(SENSOR_4>60){ //白の時
migi2; //右に旋回
t0=CurrentTick(); //時間をリセット
} else if(SENSOR_4>50){ //白よりの灰色の時
migi1; //右に曲がる
t0=CurrentTick(); //時間をリセット
} else if(SENSOR_4>45){ //黒よりの灰色の時
hidari1; //左に曲がる
t0=CurrentTick(); //時間をリセット
} else if(SENSOR_4>30){ //黒の時
hidari2; //左に旋回
} else{ //そのほかの時
mae; //前に進む
t0=CurrentTick(); //時間をリセット
}
Wait(STEP);
}
Off(OUT_BC); //停止する
Wait(1000); //0.1秒待つ
}
このプログラムは授業で習ったものとほとんど同じなので説明は省略するが、あまりスムーズにならなかったので
~線の黒さによって速度を変えるプログラムにすればよかったと感じた。
~線の右をトレースするプログラムも書いたが、使わなかったので省略する。
**交差点の識別 [#y1cc65d5]
交差点かどうかを判断するのにはライントレース中の真っ黒である時間で認識させる。交差点では、直線を走るときよりも、真っ黒の時間を走っている時間が長くなるので、
~そのターンにかかる時間が一定の時間を超えたときにロボットが止まるようにする。
~これを行うために、時間変数t0を用いた。測る直前の時刻を時間変数t0に代入して、このt0を基準に時間を測定する。
~このt0と現在の時刻との差を計算することによって、時間がどれくらいたったのかがわかる。なお、現在の時刻はlong t0=CurrentTick()で得られる。
~私が作ったロボットでは交差点でターンするのに0.11秒かかった。ゆえに、t0と現在の時刻との差CurrentTick-t0が0.11より大きいとき、機体が止まるようにする。
~また、ifやelse ifの中にto=CurrentTick()をいれ、toと現在の時刻との差を0にすることで、黒の値以外の値をとっているときに変数の値CurrentTick()が増え続けていき、
~0.11秒を超えてしまい、交差点以外のところで止まるのを防ぐ。
#ref(./スライド2.JPG,75%,コースの画像)
**全体のプログラム [#w9cdab38]
task main()
{
line_follow1(); //ライントレース
migi1; //D地点で車体をまっすぐに
Wait(400);
Off(OUT_BC);
mae; //前に進む
Wait(300);
Off(OUT_BC);
line_follow1(); //ライントレース
hidari1; //G地点で交差点を曲がる
Wait(400);
Off(OUT_BC);
line_follow1(); //ライントレース
hidari2; //H地点で左に旋回
Wait(1000);
Off(OUT_BC);
mae; //ボールの前まで進む
Wait(800);
Off(OUT_BC);
ball; //ボールをつかむ
u_turn; //Uターンする
line_follow1(); //ライントレース
hidari1; //J地点で車体をまっすぐに
Wait(300);
Off(OUT_BC);
mae; //ゴールへ入る
Wait(500);
Off(OUT_BC);
}
*まとめ [#u72cd89f]
ただ単にライントレースをすることとボールを捕まえることは簡単にできたが、交差点の認識や急カーブを曲がることは難しかった。
~僕が書いたプログラミングでは、J地点を過ぎた後のカーブを交差点と間違えて止まってしまったので、t minとt maxを使って無視するプログラムにすればよかったと思いました。
~ロボットに関して言えば車体のシンプルで、ボールをつかむ機構も少ないパーツで作ることができたので、前回の反省を生かせていると思いました。