・指定のフィールド内で、缶を転がしてゴールに運ぶロボットを作成する。 ・フィールドは160cm×80cmの長方形。 ・制限時間は三分間。所定の位置からスタート。 ・その場で一回のみ再チャレンジができる。納得できなければ全チーム終了後再度チャレンジが可能。 ・缶をゴールに運ぶと本数に応じて得点。 ・障害物の缶を倒す又は円から出すとマイナス得点。 ・各チームとTAが様々な角度から採点(技術点)。 ・技術点の平均を競技の得点に加算して順位を決める。
ロボット製作者:tomy以外の班員全員でやりました。
高度な課題なだけに皆頭を悩ませた。
?最初の構想は二台のロボットを使用するものだった。缶を取るロボットは、缶の下にアームを突っ込んで、持ち上げて運ぶ構造だった。しかし、”受け渡しをどのように行うか?”というところで引っかかってしまった。アームに乗っている缶が重くて、モーターの力で引っ張り出すのが難しかったからだ。
?そこで、受け渡しを行わずに一台のロボットでゴールまで運ぶ案が出た(ルールを見る限り違反ではないはずです)。そもそも受け渡しのリスクを負ってまで二台のロボットを使うメリットはないように思えたからだ。缶を取るときにはアームをかぶせてゴールまで転がしていき、最後はゴリ押しで押し込んでしまおうというアイデア。移動はライントレースに頼る。いろいろ試したがプログラム次第でできそうである。
それだと部品がかなり余るので、応援する(?)ロボットを作ってみた。マジックハンドを上下しながら応援(?)してくれる。ビジュアルにかなりこだわったのだが、これは本体の進路の邪魔になるので出番はなかった(涙
製作にあたって問題になったのは、
・アームが重すぎて移動中に下りてしまうところ。これはウォームギアを使った逆回転を止める機構で解決した。
・アームを下ろしても缶が重みで動かず、アームがすべってしまうので、アームの先に引っ掛ける機構(ゴムタイヤなど)をつけた。
・更に重心が前によりすぎてバランスが悪くなったので、後ろに重しのタイヤを載せて解決した。
・最後に缶を押し込むときにうまくいかなかったが、車体の下に斜めのでっぱりをつけることで、スムーズに押し込むことができた。
製作日:7/31 製作者:tomy
task main() { OnFwd(OUT_B); //アームを上げる Wait(50); OnFwd(OUT_A+OUT_C); //前進。このときは距離を測って、その分だけ進むようWaitで調節した。 Wait(100); Off(OUT_A+OUT_C); OnFwd(OUT_A); //一回目の右折。 Wait(60); OnRev(OUT_C); Wait(60); Off(OUT_A+OUT_C); OnFwd(OUT_A+OUT_C); //1.5秒間前進。 Wait(150); Off(OUT_A+OUT_C); OnFwd(OUT_A); //2回目の右折 Wait(60); OnRev(OUT_C); Wait(60); Off(OUT_A+OUT_C); OnFwd(OUT_A+OUT_C); //1.4秒間前進。 Wait(140); Off(OUT_A+OUT_C); //ここに缶を掴む動作が来るはずだった。 OnRev(OUT_A+OUT_C); //後進 Wait(80); Off(OUT_A+OUT_C); OnFwd(OUT_C); //帰り道。左折 Wait(60); OnRev(OUT_A); Wait(60); Off(OUT_A+OUT_C); OnFwd(OUT_A+OUT_C); //1.4秒間前進 Wait(140); Off(OUT_A+OUT_C); OnFwd(OUT_C); //左折 Wait(60); OnRev(OUT_A); Wait(60); Off(OUT_A+OUT_C); OnFwd(OUT_A+OUT_C); //1.4秒間前進。スタート地点に帰ってきた。 Wait(140); Off(OUT_A+OUT_C); SendMessage(1); //受け渡しのためのメッセージを送る
このプログラムは最初2台でやるものだと考えて作ったものだから前半までしかできてません。ライントレースは行わず、長さを測って、それにあわせて時間を指定する予定でした。動きに関しては、行って帰ってくるところだけですがうまくいったりいかなかったりしました。同じ時間を指定しているのに何でだろう?結局分からなかった。
製作日:8/1 製作者:tomy
task main() { SetSensor(SENSOR_1,SENSOR_LIGHT); //センサー1を光と定義 SetSensor(SENSOR_3,SENSOR_LIGHT); //センサー3を光と定義 OnFwd(OUT_B); //アームを上げる Wait(40); Off(OUT_B); OnFwd(OUT_A+OUT_C); //前進 Wait(100); Off(OUT_A+OUT_C); OnFwd(OUT_C); //1回目の右折 Wait(70); Off(OUT_C); ClearTimer(0); //タイマーをリセット while(Timer(0) <=30) //タイマーが30以上になるまで以下(ライントレース)を実行。 { if(SENSOR_1 < 45) //センサー1が反応すると… { OnFwd(OUT_A); //軌道を左に調整 Off(OUT_C); }else{ Off(OUT_A); OnFwd(OUT_C); } if(SENSOR_3 < 45) //センサー3が反応すると… { OnFwd(OUT_C); //軌道を右に調整 Off(OUT_A); }else{ Off(OUT_C); OnFwd(OUT_A); } } OnFwd(OUT_A+OUT_C); //前進 Wait(150); Off(OUT_A+OUT_C); OnFwd(OUT_C); //右折 Wait(70); Off(OUT_C); while(Timer(0)<=15) { if(SENSOR_1<45) //センサー1が反応すると… { OnFwd(OUT_A); Off(OUT_C); }else{ Off(OUT_A); OnFwd(OUT_C); } if(SENSOR_3 <45) //センサー3が反応すると… { OnFwd(OUT_C); Off(OUT_A); }else{ Off(OUT_C); OnFwd(OUT_A); } } OnFwd(OUT_A+OUT_C); //前進 Wait(180); Off(OUT_A+OUT_C); OnRev(OUT_B); //カンをつかむ Wait(50); Off(OUT_B); OnRev(OUT_A+OUT_C); //後進 Wait(200); Off(OUT_A+OUT_C); OnRev(OUT_A); //右折 Wait(60); Off(OUT_A); while(Timer(0)<=30) { if(SENSOR_1<45) //センサー1が反応すると… { OnFwd(OUT_A); Off(OUT_C); }else{ Off(OUT_A); OnFwd(OUT_C); } if(SENSOR_3 <45) //センサー3が反応すると… { OnFwd(OUT_C); Off(OUT_A); }else{ Off(OUT_C); OnFwd(OUT_A); } } OnFwd(OUT_A+OUT_C); //前進 Wait(120); Off(OUT_A+OUT_C); OnFwd(OUT_A); //右折 Wait(60); Off(OUT_A); while(Timer(0)<=30) { if(SENSOR_1<45) //センサー1が反応すると… { OnFwd(OUT_A); Off(OUT_C); }else{ Off(OUT_A); OnFwd(OUT_C); } if(SENSOR_3 <45) //センサー3が反応すると… { OnFwd(OUT_C); Off(OUT_A); }else{ Off(OUT_C); OnFwd(OUT_A); } } OnFwd(OUT_A+OUT_C); //前進 Wait(400); Off(OUT_A+OUT_C); while(Timer(0)<=30) { if(SENSOR_1<45) //センサー1が反応すると… { OnFwd(OUT_A); Off(OUT_C); }else{ Off(OUT_A); OnFwd(OUT_C); } if(SENSOR_3 <45) //センサー3が反応すると… { OnFwd(OUT_C); Off(OUT_A); }else{ Off(OUT_C); OnFwd(OUT_A); } } OnFwd(OUT_A+OUT_C); //前進 Wait(50); Off(OUT_A+OUT_C); OnFwd(OUT_A); //右折 Wait(60); Off(OUT_A); while(Timer(0)<=30) { if(SENSOR_1<45) //センサー1が反応すると… { OnFwd(OUT_A); Off(OUT_C); }else{ Off(OUT_A); OnFwd(OUT_C); } if(SENSOR_3 <45) //センサー3が反応すると… { OnFwd(OUT_C); Off(OUT_A); }else{ Off(OUT_C); OnFwd(OUT_A); } } OnFwd(OUT_A+OUT_C); //前進 Wait(150); Off(OUT_A+OUT_C); OnFwd(OUT_A); //右折 Wait(60); Off(OUT_A); OnFwd(OUT_A+OUT_C); //前進 Wait(30); Off(OUT_A+OUT_C); OnFwd(OUT_B); //アームをあげる Wait(50); Off(OUT_B); OnFwd(OUT_A+OUT_C); //シュートぉ〜!! Wait(100); Off(OUT_A+OUT_C); }
・このプログラムからはロボット一台での作業を前提に、ライントレースを導入した。タイマーで時間を計って、 このプログラムはちゃんと動かないうえに長すぎてすぐボツになってしまった。実際長すぎた…。
製作日:8/1〜8/2 製作者:tomy
#define THRESHOLD 40 #define left(t) OnFwd(OUT_A);OnRev(OUT_C);Wait(t); //左折を定義 #define right(t) OnFwd(OUT_C);OnRev(OUT_A);Wait(t); //右折を定義 #define go(t) OnFwd(OUT_A+OUT_C);Wait(t); //前進を定義 #define back(t) OnRev(OUT_A+OUT_C);Wait(t); //後退を定義 #define down(t) OnFwd(OUT_B);Wait(t); //アームを下げる動作 #define up(t) OnRev(OUT_B);Wait(t); //アームを上げる動作 int x; //黒線を数えるための変数を定義。 int SL1; int SL2; int SR1; int SR2; task main() { SetSensor(SENSOR_1,SENSOR_LIGHT); //センサー1を光と定義 SetSensor(SENSOR_3,SENSOR_LIGHT); //センサー3を光と定義 x= 0 ; //変数xに0を代入 SL1=SENSOR_1; SR1=SENSOR_3; while(true){ SL2=SL1; SL1=SENSOR_1; SR2=SR1; SR1=SENSOR_3; if((SL1 < THRESHOLD && SR1 < THRESHOLD) && (SL2 > THRESHOLD || SR2 > THRESHOLD)) {x=x+1; //黒線を横切る度にxに数値を加算し、回数を数える if(x == 2) //2回目に黒線にあたるとき {go(40); //1回目の右折 right(90);} if(x == 4) //4回目に黒線にあたるとき {go(40); //2回目の右折 right(80); } if(x == 5) //5回目に黒線にあたるとき {Off(OUT_A+OUT_C); SetPower(OUT_A+OUT_C,OUT_HALF); down(80); //アームを下げて缶を掴む Off(OUT_B); back(140); //缶を引っ張り出す right(120); //右折 } if(x == 6) //6回目に黒線にあたるとき {left(80);} //右折する if(x == 9) //9回目に黒線にあたるとき {go(40); left(90);} //スタートを通り越し、ゴールに向かって左折 if(x== 12) //12回目に黒線にあたるとき {go(40); left(90);} //もう1回左折 if(x == 14) //14回目に黒線にあたるとき {go(40); //↓左折してアームを上げ、缶を押し込む。そのまま後退。 left(90);up(60);go(200);back(200);} if(x == 15) //15回目に黒線にあたるとき {back(40);left(90);} if(x == 17) //17回目に黒線にあたるとき {go(40);right(90);x=0;} } if((SENSOR_1< THRESHOLD)&&(SENSOR_3>THRESHOLD)){ Off(OUT_A+OUT_C); OnFwd(OUT_C); OnRev(OUT_A); //右旋回 Wait(4);} if ((SENSOR_3<THRESHOLD)&&(SENSOR_1>THRESHOLD)){ Off(OUT_A+OUT_C); OnFwd(OUT_A); //左旋回 OnRev(OUT_C); Wait(4);} else { OnFwd(OUT_A+OUT_C);}
if*1
{OnFwd(OUT_A+OUT_C);} //前進 }}
このプログラムは光センサーを使って進むロボである。その方法とは、光センサーがラインの黒いところに2つとも重なるときの回数を計算していって曲がるか曲がらないかを決めていくというものだ。フィールド上の黒線の配置をうまく利用した画期的な案であった。 最初どうやって進ませようかわからなかったのだが、関数を使っている班があって、その班員に関数の使い方を教えてもらいうまく進めるようになった。しかし、今度はロボット本体の方に問題ができた。アームの力が弱くアームを上げてもすぐ降りてくるという始末だ。その改良方法とはギアを使ってストッパー(?)を作ったことだ。このおかげでアームが降りてくることはなくなった。 ライントレースの方は、失敗するときもあるが、成功率は断然よくなった。黒線を数えるのがうまくいかなかったりもしたが、実験に使ったフィールドの黒線が薄かった為とわかった。缶を掴む動作に少々不安があったが、アームの先を強化することで缶をしっかり保持できるようになった。
A3班の発表は四番目。一度目のチャレンジは2つ目のカーブをうまく曲がることができず失敗。二度目は缶のところにたどり着いたのだが、缶を掴もうとしたアームが宙を泳いだ。最後の挑戦で缶を掴むことができた!しかし、帰り道を間違えて壁に激突し、失敗。
・前日も夜遅くまで製作したが間に合わず、当日の朝からプログラムとロボの微妙な調節で大変だった。しかし、缶を1つも運ぶことができなかった。もう少し時間があれば何とか1つ運ぶことができたかもしれない。 Fuji
・缶を取るとこまでできたが自分のプログラムのミスで曲がる場所を一つ早く曲がってしまいゴールまでたどり着かなかった。 tomy
・テスト直後で時間的な余裕がなかった。いいアイデアが思いつかず、結果として他の班と似たような構造のロボットになった。
当日はうまくいかなかったのが残念。(by Shu)
・上とかぶるが1つも缶を運ぶことができなくて残念だった。缶を運ぶことができたチームがほとんどなかったので今回の課題はかなり難しかったのではないだろうか。 Fuji
・細かい微調整もなんだか空回り気味で練習ではけっこううまくできていたのに本番ではライントレースさえ失敗してしまった。あまりの暑さにロボットも調子が悪かったのでは? kammy
・最初のほうは何をしていいのかわからなかったが過去のページをみたり班の人にいろいろ教えてもらいながらなんとか(かなりぎりぎりだが)ついていくことができた。今までブロックを組み立てたことはあったがプログラムを作ったりしたことはなかったのでいい経験になって良かった。 Fuji
・ロボットを動かすためにはあらゆるプログラムを作成しなくてはならないと知った。自分にとってそれは難しい作業だった。この授業を通して違う学科の方々と交流することができ、また1つの目標に向かって一緒に作業することができよかった。 Kayo
・最初から最後まで慣れないプログラミングとかのせいですごくたいへんだった。機械的といえば一連の作業を完璧にすばやく行うイメージがあったけど、やはり機会も人間のつくるものなので、いかに脆いかがわかった。なのでプログラミングをする際には何が起こる可能性があるかというあらゆることを考えなくてはいけないと思った。 kammy
・毎回提出期限間際まで本格的に行動できなくて残念だった。それ以外は割と良くできてた授業だったです。でも今度はもっと積極的に行動していかなくてはならないとつくづく思いました。この経験をほかのことにも生かしていきたいと思います。 tomy
・ロボットが実は結構アナログなものであることを思い知った。どんな風に問題解決に向かっていくか、その段階を学ぶことができた。 shu