- 追加された行はこの色です。
- 削除された行はこの色です。
[[2006a/MemberOnly/進行状況C]]
#hr
CENTER:&size(25){ロボコン大会のページ (缶を転がして所定の位置まで運ぶ)};
#hr
*目次 [#k6b4b665]
#contents
**制作者 [#t2e49820]
たかくん
ほたる
サルバカ
子供の頃から神童
二等兵
二等兵
ツノハラ
**ロボットの紹介 [#w7acf935]
***缶を受け渡す側のロボット(前半) [#qfdba10f]
#ref(2006a/C1/ロボコン/dscn2747_Medium.jpg,50%)
四方に支柱が付いているが基本的には二輪で動く。
缶を掻き込むための大きな爪に、逆回転したときに缶を掻き出す小さな爪が付いている。
上から見ると・・・
#ref(2006a/C1/ロボコン/dscn2748_Medium.jpg,50%)
缶を複数取り込むことばかりに執着したがために、空虚感さえ漂うゆとり設計。これが後に「機体の旋回に缶がついて来ない」という悲劇を生む。
メッセージの送受信のために無茶な向きに着けられたRQC本体も実に危なっかしい。
**モーターとセンサーの役割 [#efcfabdd]
***缶を受け取る側のロボット(後半) [#t2cba388]
#ref(2006a/C1/ロボコン/dscn2655_Medium.jpg,50%)
モーターとセンサーの役割
モーターは3つ使い、そのうち2つはタイヤに使った。残りの1つは缶にかぶせる囲いを上げたり下げたりするものに使った。
黒い線上を走るとき、ライントレースをせずに、それぞれ格子の一辺を走る長さを測って走らせることにした。
また、タッチセンサーも使っており、2つ使って感度を上げ、そうして、缶が転がってきたときにロボットにぶつかったら囲いを下ろす仕組みとした。
**プログラムの概要 [#p1c93f79]
***缶を受け渡す側のロボット(前半) [#e1a264f6]
最初の直進にのみライトセンサーを使用(スタート時の配置による影響を抑えるため)、以降は時間調整でコースを辿る。モーターBから繋がる2つの爪の回転により、缶を回収。爪の逆回転で缶を転がし、後続機に受け渡す(はずだった)。
***缶を受け取る側のロボット(後半) [#wc549b9c]
まず、転がってきた缶をタッチセンサーで感知したら、缶を閉じ込める囲いを下ろす。次に、時間で計った分だけ走らせて、缶を運ぶ。そして、缶を入れるゴールの手前まできたら、囲いを上げ、そのまま缶を押していき、木の塀にぶつかっても、そのまま缶を押して缶を押し出して、ゴールに入れる。
**プログラム [#jc971973]
void turn_right(int t)
***缶を受け渡す側のプログラム(前半) [#j5a27383]
#define TURN_TIME 467 //一回転に要する時間を定義
#define STR10_TIME 62 //直進100mmに要する時間の定義
task main()
{
SetPower(OUT_A,5); //モーターの出力調節
SetPower(OUT_C,7);
SetPower(OUT_B,1);
SetSensor(SENSOR_1,SENSOR_LIGHT); //センサーの定義
SetSensor(SENSOR_3,SENSOR_LIGHT);
OnFwd(OUT_A+OUT_C); //暗線まで直進
until (SENSOR_1 < 36&&SENSOR_3<36);
Off(OUT_A+OUT_C);
OnFwd(OUT_C); //右90°旋回
OnRev(OUT_A);
Wait(80);
OnFwd(OUT_A+OUT_C); //40cm直進
Wait(155);
Off(OUT_A+OUT_C);
OnFwd(OUT_C); //右90°旋回
OnRev(OUT_A);
Wait(100);
OnFwd(OUT_A+ OUT_C); //30cm直進
Wait(STR10_TIME*3);
Off(OUT_A+OUT_C);
OnFwd(OUT_B); //缶(中央)回収
Wait(130);
Off(OUT_B);
OnRev(OUT_A+OUT_C); //30cm後退
Wait(STR10_TIME*3);
Off(OUT_A+OUT_C);
OnFwd(OUT_C); //右90°旋回
OnRev(OUT_A);
Wait(100);
OnFwd(OUT_A+OUT_C); //30cm直進
Wait(STR10_TIME*3);
OnFwd(OUT_A); //左90°旋回
OnRev(OUT_C);
Wait(100);
OnFwd(OUT_A+ OUT_C); //50cm直進
Wait(STR10_TIME*5);
Off(OUT_A+OUT_C);
OnRev(OUT_B); //缶(中央)を転がす
Wait(260);
Off(OUT_B);
SendMessage(1); //メッセージ送信
Wait(500);
ClearMessage();
until(Message()!=2); //メッセージ受信
Wait(700);
start main;
}
***缶を受け取る側のプログラム(後半) [#ufeda6a6]
void turn_right(int t) //右に回る
{
OnFwd(OUT_A);
OnRev(OUT_C);
Wait(t);
}
void turn_left(int u)
void turn_left(int u) //左に回る
{
OnFwd(OUT_C);
OnRev(OUT_A);
Wait(u);
}
void go_straight(int v)
void go_straight(int v) //前進
{
OnFwd(OUT_A+OUT_C);
Wait(v);
}
void back(int w)
void back(int w) //後退
{
OnRev(OUT_A+OUT_C);
Wait(w);
}
int time;
int time; //変数を定義
int time_1;
task main()
{
SetSensor(SENSOR_1,SENSOR_LIGHT);
SetSensor(SENSOR_1,SENSOR_LIGHT); //センサーを定義
SetSensor(SENSOR_2,SENSOR_TOUCH);
SetSensor(SENSOR_3,SENSOR_LIGHT);
SetPower(OUT_A,5);
SetPower(OUT_C,7);
ClearMessage();
until(Message()!=0);
until(Message()!=0); //メッセージが送られてくるまで待つ
ClearTimer(1);
OnFwd(OUT_A+OUT_C);
until(SENSOR_2==1);
OnRev(OUT_B);
ClearTimer(1); //時間を計る
OnFwd(OUT_A+OUT_C); //前進する
until(SENSOR_2==1); //缶にぶつかるまで
OnRev(OUT_B); //アームを下ろし缶をつかむ
Wait(30);
Off(OUT_A+OUT_B+OUT_C);
time_1=FastTimer(1);
back(time_1);
back(time_1); //スタート位置まで戻る
ClearTimer(0);
OnRev(OUT_A+OUT_C);
until(SENSOR_1<40&&SENSOR_3<40);
ClearTimer(0); //時間を計る
OnRev(OUT_A+OUT_C); //後退する
until(SENSOR_1<40&&SENSOR_3<40); //真ん中の線まで
time=FastTimer(0);
turn_left(400/4);
back(100+time);
turn_right(400/4);
Off(OUT_A+OUT_B+OUT_C);
turn_left(400/4); //次にバックするために準備
back(100+time); //後退する
turn_right(400/4); //回転してゴールの方を向く
Off(OUT_A+OUT_B+OUT_C); //缶を落ち着かせるために止める
Wait(200);
OnFwd(OUT_B);
OnFwd(OUT_B); //アームを上げる
Wait(40);
Off(OUT_B);
go_straight(200);
OnRev(OUT_A+OUT_C);
until(SENSOR_1<40&&SENSOR_3<40);
turn_left(380/4);
go_straight(90+time);
turn_right(380/4);
go_straight(50);
OnFwd(OUT_A+OUT_C);
until(SENSOR_1<40&&SENSOR_3<40);
Off(OUT_A+OUT_B+OUT_C);
go_straight(200); //缶を入れるために前進
OnRev(OUT_A+OUT_C); //缶を入れ終わったら後退
until(SENSOR_1<40&&SENSOR_3<40); //真ん中の線まで
turn_left(380/4);次に前進するために準備
go_straight(90+time); //前進する
turn_right(380/4); //マシンを正面に向ける
go_straight(50); //真ん中より後ろの位置にあるかもしれないのでそのぶん前進
OnFwd(OUT_A+OUT_C); //前進する
until(SENSOR_1<40&&SENSOR_3<40); //スタート時の位置まで
Off(OUT_A+OUT_B+OUT_C); //マシンを止める
SendMessage(2);
SendMessage(2); //メッセージを送る
Wait(400);
}
**缶を受け取る方のプログラム(後半) [#v4087dad]
#define TURN_TIME 467
#define STR10_TIME 62
task main()
{
SetPower(OUT_A,5);
SetPower(OUT_C,7);
SetPower(OUT_B,1);
SetSensor(SENSOR_1,SENSOR_LIGHT);
SetSensor(SENSOR_3,SENSOR_LIGHT);
OnFwd(OUT_A+OUT_C);
until (SENSOR_1 < 36&&SENSOR_3<36);
Off(OUT_A+OUT_C);
OnFwd(OUT_C);
OnRev(OUT_A);
Wait(80);
OnFwd(OUT_A+OUT_C);
Wait(155);
Off(OUT_A+OUT_C);
OnFwd(OUT_C);
OnRev(OUT_A);
Wait(100);
OnFwd(OUT_A+ OUT_C);
Wait(STR10_TIME*3);
Off(OUT_A+OUT_C);
OnFwd(OUT_B);
Wait(130);
Off(OUT_B);
OnRev(OUT_A+OUT_C);
Wait(STR10_TIME*3);
Off(OUT_A+OUT_C);
OnFwd(OUT_C);
OnRev(OUT_A);
Wait(100);
OnFwd(OUT_A+OUT_C);
Wait(STR10_TIME*3);
OnFwd(OUT_A);
OnRev(OUT_C);
Wait(100);
OnFwd(OUT_A+ OUT_C);
Wait(STR10_TIME*5);
Off(OUT_A+OUT_C);
OnRev(OUT_B);
Wait(260);
Off(OUT_B);
SendMessage(1);
Wait(500);
ClearMessage();
until(Message()!=2);
Wait(700);
start main;
}
**工夫した点、苦労した点 [#v61ccbd8]
-缶を最後押し出すとき、どのようにして木の塀を越えるか
これは、ロボットが塀にぶつかった時にロボットが上に押し出されたことから考えて、斜めの傾斜のついたブロックをロボットの前方につけた。そしてロボットが塀にぶつかったときに、さらにロボットが缶を押し出すと、缶が傾斜を上り、そうして塀を乗り越える。これは、限られたモーターを使って缶を上げたり閉じ込めたりしなければならないというときに、ロボットを作るときにおいて、工夫して解決した点であった。
-黒い線上を走らせるときに、どのようにしてライントレースをさせるか
ここでは、今までの、1本の線上をライントレースさせるものとは違い、いくつもの線が交差し、交点上を旋回したり、直進したりしなければならないということが問題であった。最初は、ライントレースでやろうと思い、まず、1つのライトセンサーによってライントレースしようとした。しかし、1つのライトセンサーでやったのでは、やはり黒い線上の境界線上しか走らず、交点という、黒い所の固まりを処理することは難しいという結論になった。そこで、ライトセンサー2つでやることになった。これで、その考え方とは、2つのライトセンサーが、黒い線を挟む形で進んでいくものとした。つまり、黒い線上の脇の白いところをセンサーは進んでいくということにした。そこで、黒い線上に向かって左側のセンサーが乗っていたら、白いところに戻したいということで、左に旋回し、右側のセンサーが黒い線上に乗っていたら、右に旋回するというようにした。さらに、線の交点では、それまで白いところを走っていたセンサーが、黒いとろに乗るため、そこで、2つのセンサーが黒いところに乗ったらという条件で、そのときに、旋回や、直進をすることとした。そうして、最初の格子の一辺を走ったまでの時間を変数で定義した上で、記憶し、その時間だけ格子単位でまたライントレースさせていくこととした。
しかしここで問題があった。それは、ifで条件としてやったが、どうしても条件が重なってしまって、うまく行動しないのである。黒い線上に来たら左に旋回し、または右に旋回しというようにしていて、さらに、両方のセンサーが黒いところにきたら、一方方向に旋回させるなどというようにしてあった。つまりここで、交点のところで条件が重複し、左旋回と右旋回が連続しておこり、結果的に直進するか、一方方向に旋回するかわからなくなってしまうのである。これより、右のセンサーが今度は白い線上に来たら左旋回するというようにしても問題がある。それは、ともにともに白いところにセンサーがきたときに直進するというようにしていたが、その条件と今度は重複し、うまく行動しないのである。
そこで、もしかしたらずれることはあるかもしれないが、簡単で、確実な、時間を計って走らせることにした。格子の一辺を走るのにかかる時間を缶を持ったときと、持たないときとでそれぞれ調べ、その分だけ走らせることにした。
-缶を閉じ込める囲いをどのようにして作るか
缶がロボットに比べて大きいため、それを囲むような大きな囲いを作るのは大変だった。モーターも残り一つしかないため、それで多くの動きもできないため、缶を持ち上げたり、運んだり、缶を引き寄せて持ったり、最後に缶を下ろしたりということが難しかった。そこで、囲いを下ろして缶を閉じ込めるというだけの動きをして、さらに、最後ゴールに押し込むという動作は、モーターを使わずにやることにした。
-缶を閉じ込めるときにはどのようにして囲いを下ろすか
これは、プログラムの話である。ここでは、一見簡単なように思えて、難しかった。缶がタッチセンサーに当たって、反応しても、そこで缶はバウンドし、前方へと缶がいってしまう。囲いが下ろすのが遅くて、囲いの中に缶が入らなくなってしまう。そこで、囲いを上げたままにして、缶が転がってきたら、こちらも前進していく。そして、缶がタッチセンサーに当たったら、前進と同時進行で囲いを下ろし、下ろしきったらまた線上を走っていくものとした。これで缶が跳ね返ってはなれていくものを追いかけるようにしながら囲いを下ろすようにした。
-複数の缶を運ぶために何をするべきか
前半を受け持つロボットにとってこれほど気になる課題はないのに、大会では缶を1つ運ぶために必死だったのだから悲しい話だ。我々の班でも2本目、3本目の缶を運ぶための機構の案はあったのだが、製作すら完了しなかった。最も難解であったのが「動力の確保」だ。左右の車輪に一つずつ、メインの回収機構(大きな爪)に一つのモーターを使っていたため、他の回収機構を動かすのは大変な負担だった。「機体後部にキャタピラを着け、左右の缶に押し付け手繰り寄せる」という案を実現させたかったのだが、ギアでつなぐとパーツか増える一方で回転が重くなるし、プーリーではそれこそ力不足であった。限られたパーツで目的を果たすには、綿密な計画・設計によって巧みにパーツをケチる技術が必要なのだと思い知った。
**ロボコンの結果発表!!! [#a6f010fc]
一回目はマシン整備不備のため棄権!?
二回目はやっとマシンができ、スタート位置につく
&ref(2006a/C1/ロボコン/dscn2711_Medium.jpg,50%);初めてのこの場にちょっと緊張気味です
そして・・・
&ref(2006a/C1/ロボコン/dscn2712_Medium.jpg,50%);見事な暴走っぷりで缶を受け渡すことができず!!!
俺らのロボコンは終わった・・・
**ロボコンを終えての感想 [#p097c409]
ロボコンは、最後の課題とあり、気合を入れて取り組み始めたのだが、まずロボットがなかなか組み立てられなかった。その時点でロボコン当日までかかってしまった。ちょっと準備が足りなかったなと思った。でも、なんとか缶を取ることまで成功でき、とてもうれしく思った。準備をしっかりしていれば、缶を受け渡し、入れるまでできたなと思った。ロボコン事態も缶を入れる事ができた班は2班しかなかったのに、ビックリしてしまった。やはり、この課題は難しかったのかと思った。
**コメントをどうぞ [#nef49f3f]
-要所をおさえたコンパクトかつ丁寧な考察はすばらしいかと思いますが、ロボコンの試合に関する流れや作戦等をもう少し書いてほしいです…。 -- [[まいける(TA)]] &new{2006-08-16 (水) 00:28:27};
#comment