・sakar
・yokkun
・sugaken
・arara
・フィールドは課題1で使用した紙を2枚つなぎ合わせる (詳細な図面は課題1を参照のこと)。
・図の右半分の黄色い地点には、その数字と同じ数字が書いてある紙コップが置かれている。 また左半分のA,B,Cの地点にも1から3までの数字が書かれている紙コップが置かれているが、 どのコップをどの地点に置くかは直前にサイコロを振って決める。
◦競技時間は審判が続行不能と判断するまで、あるいはリタイアするまで。
◦図の右上のスタートエリアからスタートする(課題1と同じ)。接地している部分がスタートエリア内に入って入ればよい。
◦図の左半分にある紙コップを集めて、それぞれ右半分にある同じ番号の紙コップに重ねる。
◦右半分の紙コップは10cm内の移動は認める
◦開始の合図から5秒以内にスタートボタンを押す作業を完了すること。
◦競技が終了するまで、ロボットに触ったり人間が遠隔で操作してはならない。
◦途中でうまく動かなくなった場合、1回限り再スタートすることができる(再スタートの際に別プログラムで起動してよい)。
◦同じ番号の紙コップに重ねることができれば、1組で10点
◦番号が1違いの紙コップに重ねれば、1組で2点
◦番号が2違いの紙コップに重ねれば、1組で0点
◦最終的な紙コップの位置が10cm以上動いた場合は、その1組の点数を半分にする
技術点の計算方法以下の動作の精度・スピード・確実性などを含めた技術的な工夫や芸術性について他の全てのチームが20点満点で採点し、その平均点を求める。
◦紙コップを取りにいくまでの動作 (2点)
◦紙コップを掴む動作 (4点)
◦紙コップをを運ぶ動作(3点)
◦紙コップを重ねる動作(4点)
◦2台のRCXまたはNXTの連携の良さ(3点)
◦自立型のロボットとしての形や動作の美しさ、斬新さ(2点)
◦その他 (2点)
本体は前回の課題でできなかったことを色々実践してみた。それを形にしたのが上のロボットである。
アームは先生が作っていたものを参考にして作った。モーターを回すことによって歯車が上のように回り、アームが上がるようになっている。このアームには16個の歯車がついている。ここで苦労したことはうまく歯車が回らなかったことである。まず、歯車の大きさが合わず、どの組み合わせがうまく合うかを考えるのに苦労した。モーターの位置を10センチほどの高さにしないとアームが上がらなかったのでこのような問題がおきた。
そこで上の図のように少し歯車の位置を前後にずらしてみた。これによりすこし空いていた隙間がなくなりスムーズに回るようになった。
次に出てきた問題としてアームが上がらないということがでてきた。確かにモーター1つで重量のあるアームを上げるのは難しい。そこで、モーターを2つにして持ち上げることにした。これでパワーが増しスムーズにアームが上がるようになった。
他に工夫した点としてモーターを2つにしたので、ブロックが外れて歯車が空回りすることが多くなったので穴のあるブロックを使ってそこに棒を通したり、細長い穴の開いた部品で固定した。
いざ走らせてみてボールを取らせてみると、案外ボールをアームの中に入れることが出来なかったので、上の写真のように右アームだけもう一つ腕をつけて届く範囲を広げた。
車体はタイヤ2つ本体2つというような形にした。本体は最初は2つを縦に並べて置いていたのだが、車体が大きくなりうまくタイヤが回らなくなりカーブを曲がれなかったので片方を縦に置いた。そのために細長い穴の開いたブロックで固定した。
センサーはコップの明るさを識別するものとトレースをするセンサーの2つを使用した。
赤丸の方がトレース用。緑丸がコップ識別用である。工夫したところとしてコップ用のセンサーを出来るだけ前に出すようにしたことである。アームの間にブロックをはめそこにつけた。
まずAのコップを取りに行くようにしてそこからコップの色でどのコップへ向かうかと判断させるプログラムを作った。また、動きと並行してアームを動かすために通信機能を使うようにした。
#define CUPA1 111 #define CUPA2 112 #define CUPA3 113 #define GOFOR 200 #define GOBACK 201 #define ARMUP 202 #define ARMDOWN 203 #define GOA1 121 #define GOA2 122 #define GOA3 123 #define SKIT 45 //トレースのしきい値 #define JUDGE 45 //紙コップ判断のしきい値 #define HIGHPOWER 7 #define LOWPOWER 1 #define set_power_H SetPower(OUT_AC,HIGHPOWER);//速度を速める #define set_power_L SetPower(OUT_AC,LOWPOWER);//速度を落とす #define turn_left1 set_power_L;OnFwd(OUT_A); OnRev(OUT_C); //左旋回 #define turn_left0 set_power_L;OnFwd(OUT_A); Off(OUT_C); //左折 #define turn_right0 set_power_L;OnFwd(OUT_C); Off(OUT_A); //右折 #define turn_right1 set_power_L;OnFwd(OUT_C); OnRev(OUT_A); //右旋回 #define go_forward set_power_H; OnFwd(OUT_AC); //直進 #define go_back(s) OnRev(OUT_AC); Wait(s); Off(OUT_AC); //後進s秒間 #define STEP 1 //ライントレースの判断時間 #define noMAX 30 //右に行き過ぎた時、転回の最大回数 #define NOSTEP 200 //右に行き過ぎた時、左に戻るための時間 #define SENDTIME 300
sub line_trace(tim) { SetSensor(SENSOR_2, SENSOR_LIGHT); //ライントレース用の光センサー int nonline=0; ClearTimer(1); while(Timer(1) <= tim){ if (SENSOR_2 < SKIT-6){ turn_left1; } else if (SENSOR_2 < SKIT-3) { //しきい値よりも6低いと左旋回 turn_left0; //しきい値よりも3低いと左折 } else if (SENSOR_2 < SKIT+3) { //しきい値よりも3高いと右折 go_forward; //しきい値よりも6高いと右旋回するが、 } else { //右旋回をしすぎて逆方向に行きそうであれば左旋回 if(SENSOR_2 < SKIT+6) { //して戻る turn_right0; } else { while (nonline < noMAX){ turn_right1; nonline++; } turn_left1; Wait(noMAX*STEP*NOSTEP); } nonline=0; } Wait(STEP); //停止 } }
コップの色の識別方法として、なにも塗ってないコップ、マジックで塗ったコップ、鉛筆で塗ったコップを使った。
task main() { SetSensor(SENSOR_3, SENSOR_LIGHT); //紙コップ識別用の光センサー go_forward; //4.3秒前に進む Wait(430); line_trace(800); //ライントレースを8秒行う while(true){
if (SENSOR_3 < JUDGE-7){ Off(OUT_AC); //センサーがコップを感知した ClearTimer(0); ときにタイマーをセットしアーム ClearMessage(); のほうの本体にメッセージを送る while((Message() != 1)||(FastTimer(0)<SENDTIME)){ SendMessage(CUPA1); } if(Message() == 1){ PlaySound(SOUND_CLICK); }else{ PlaySound(SOUND_LOW_BEEP); //音を鳴らす } Wait(50); } until(Message() == GOFOR); SendMessage(2); //メッセージを送る OnFwd(OUT_AC); //8秒前に進む Wait(80); ClearTimer(0); ClearMessage(); while((Message() != 3)||(FastTimer(0)<SENDTIME)){ SendMessage(ARMUP); } if(Message() == 3){ PlaySound(SOUND_CLICK); //音を鳴らす }else{ PlaySound(SOUND_LOW_BEEP); //音を鳴らす } Wait(50); } ClearMessage(); while(true){ if(Message() == GOA1){ SendMessage(4); //メッセージを送る OnRev(OUT_AC); //1秒後ろに下がる Wait(100); turn_left1; //3秒左に旋回 Wait(30); OnFwd(OUT_AC); //3秒前進 Wait(300); line_trace(); until(SENSOR_3 < JUDGE-7); Off(OUT_AC); //停止 go_back(100); //バック ClearTimer(0); ClearMessage(); while((Message() != 5)||(FastTimer(0)<SENDTIME)){ SendMessage(ARMDOWN); } if(Message() == 5){ PlaySound(SOUND_CLICK); //音を鳴らす }else{ PlaySound(SOUND_LOW_BEEP); //音を鳴らす } Wait(50); until(Message() == GOBACK); SendMessage(6); OnFwd(OUT_AC); //8秒前進 Wait(80); ClearTimer(0); ClearMessage(); }
else if(SENSOR_3 < JUDGE-3){ Off(OUT_AC); //停止 ClearTimer(0); ClearMessage(); while((Message() != 1)||(FastTimer(0)<SENDTIME)){ SendMessage(CUPA2); //メッセージを送る } if(Message() == 1){ PlaySound(SOUND_CLICK); //音を鳴らす }else{ PlaySound(SOUND_LOW_BEEP); //音を鳴らす } Wait(50); } until(Message() == GOFOR); SendMessage(2); OnFwd(OUT_AC); //8秒前進 Wait(80); ClearTimer(0); ClearMessage(); while((Message() != 3)||(FastTimer(0)<SENDTIME)){ SendMessage(ARMUP); } if(Message() == 3){ PlaySound(SOUND_CLICK); //音を鳴らす }else{ PlaySound(SOUND_LOW_BEEP); //音を鳴らす } Wait(50); } ClearMessage(); while(true){ if(Message() == GOA2){ SendMessage(4); //メッセージを送る line_trace(); until(SENSOR_3 < JUDGE-2); Off(OUT_AC); go_back(100); //後ろに下がる ClearTimer(0); ClearMessage(); while((Message() != 5)||(FastTimer(0)<SENDTIME)){ SendMessage(ARMDOWN); } if(Message() == 5){ PlaySound(SOUND_CLICK); //音を鳴らす }else{ PlaySound(SOUND_LOW_BEEP); //音を鳴らす } Wait(50); until(Message() == GOBACK); SendMessage(6); OnFwd(OUT_AC); //8秒前進 Wait(80); ClearTimer(0); ClearMessage(); }
else if(SENSOR_3 > JUDGE+5){ Off(OUT_AC); //停止 ClearTimer(0); ClearMessage(); while((Message() != 1)||(FastTimer(0)<SENDTIME)){ SendMessage(CUPA3); //メッセージを送る } if(Message() == 1){ PlaySound(SOUND_CLICK); //音を鳴らす }else{ PlaySound(SOUND_LOW_BEEP); //音を鳴らす } Wait(50); } until(Message() == GOFOR); SendMessage(2); //メッセージを送る OnFwd(OUT_AC); //8秒前進 Wait(80); ClearTimer(0); ClearMessage(); while((Message() != 3)||(FastTimer(0)<SENDTIME)){ SendMessage(ARMUP); //メッセージを送る } if(Message() == 3){ PlaySound(SOUND_CLICK); //音を鳴らす }else{ PlaySound(SOUND_LOW_BEEP); //音を鳴らす } Wait(50); } ClearMessage(); while(true){ if(Message() == GOA3){ SendMessage(4); //メッセージを送る go_forward; //2秒前進 Wait(200); turn_left0; //2秒左折 Wait(200); line_trace(); //ライントレース until(SENSOR_3 > JUDGE+6); Off(OUT_AC); //停止 go_back(100); //1秒下がる ClearTimer(0); ClearMessage(); while((Message() != 5)||(FastTimer(0)<SENDTIME)){ SendMessage(ARMDOWN); } if(Message() == 1){ PlaySound(SOUND_CLICK); //音を鳴らす }else{ PlaySound(SOUND_LOW_BEEP); //音を鳴らす } Wait(50); until(Message() == GOBACK); SendMessage(6); //メッセージを送る OnFwd(OUT_AC); //8秒前進 Wait(80); ClearTimer(0); ClearMessage(); } } }
#define CUPA1 111 //固有値の値 #define CUPA2 112 #define CUPA3 113 #define GOFOR 200 #define GOBACK 201 #define ARMUP 202 #define ARMDOWN 203 #define GOA1 121 #define GOA2 122 #define GOA3 123 #define HIGHPOWER 7 //パワーの数値 #define LOWPOWER 1 #define CATCHPOWER 4 #define set_power_H SetPower(OUT_AC,HIGHPOWER);// アームのモーターの強さ #define set_power_L SetPower(OUT_AC,LOWPOWER); // #define set_power_C SetPower(OUT_B,CATCHPOWER);// #define STEP 1 #define SENDTIME 300
task main() { ClearMessage(); OnRev(OUT_AC); //アームを下げる Wait(1200); Off(OUT_AC); //停止 while(true){
if(Message() == CUPA1){ SendMessage(1); //メッセージを送る OnFwd(OUT_AC); //アームを上げる Wait(50); ClearTimer(0); ClearMessage(); while((Message() != 2)||(FastTimer(0)<SENDTIME)){ SendMessage(GOFOR); } if(Message() == 2){ PlaySound(SOUND_CLICK); //音を鳴らす }else{ PlaySound(SOUND_LOW_BEEP); //音を鳴らす } Wait(50); until(Message()==ARMUP); SendMessage(3); OnRev(OUT_AC); //アームを下げる Wait(150); ClearTimer(0); ClearMessage(); while((Message() != 4)||(FastTimer(0)<SENDTIME)){ SendMessage(GOA1); } if(Message() == 4){ PlaySound(SOUND_CLICK); //音を鳴らす }else{ PlaySound(SOUND_LOW_BEEP); //音を鳴らす } until(Message()==ARMDOWN); SendMessage(5); OnFwd(OUT_AC); //アームを上げる Wait(150); ClearTimer(0); ClearMessage(); while((Message() != 6)||(FastTimer(0)<SENDTIME)){ SendMessage(GOBACK); } if(Message() == 6){ PlaySound(SOUND_CLICK); //音を鳴らす }else{ PlaySound(SOUND_LOW_BEEP); //音を鳴らす } Wait(50); until(Message()==ARMUP); SendMessage(7); OnRev(OUT_AC); //アームを下げて紙コップを積み重ねる Wait(150);}
else if(Message() == CUPA2){ SendMessage(1); OnFwd(OUT_AC); //アームを上げる Wait(50); ClearTimer(0); ClearMessage(); while((Message() != 2)||(FastTimer(0)<SENDTIME)){ SendMessage(GOFOR); } if(Message() == 2){ PlaySound(SOUND_CLICK); //音を鳴らす }else{ PlaySound(SOUND_LOW_BEEP); //音を鳴らす } Wait(50); until(Message()==ARMUP); SendMessage(3); OnRev(OUT_AC); //アームを下げて紙コップをキャッチ Wait(150); ClearTimer(0); ClearMessage(); while((Message() != 4)||(FastTimer(0)<SENDTIME)){ SendMessage(GOA2); } if(Message() == 4){ PlaySound(SOUND_CLICK); //音を鳴らす }else{ PlaySound(SOUND_LOW_BEEP); //音を鳴らす } OnRev(OUT_B); //アームを下げる Wait(800); } until(Message()==ARMDOWN); SendMessage(5); OnFwd(OUT_AC); //アームを上げる Wait(150); ClearTimer(0); ClearMessage(); while((Message() != 6)||(FastTimer(0)<SENDTIME)){ SendMessage(GOBACK); } if(Message() == 6){ PlaySound(SOUND_CLICK); //音を鳴らす }else{ PlaySound(SOUND_LOW_BEEP); //音を鳴らす } Wait(50); until(Message()==ARMUP); SendMessage(7); OnRev(OUT_AC); //アームを下げて積み重ねる Wait(150);
}if(Message() == CUPA3){ SendMessage(1); OnFwd(OUT_AC); //アームを上げる Wait(50); ClearTimer(0); ClearMessage(); while((Message() != 2)||(FastTimer(0)<SENDTIME)){ SendMessage(GOFOR); } if(Message() == 2){ PlaySound(SOUND_CLICK); //音を鳴らす }else{ PlaySound(SOUND_LOW_BEEP); //音を鳴らす } Wait(50); until(Message()==ARMUP); SendMessage(3); OnRev(OUT_AC); //アームを下げる Wait(150); ClearTimer(0); ClearMessage(); while((Message() != 4)||(FastTimer(0)<SENDTIME)){ SendMessage(GOA3); } if(Message() == 4){ PlaySound(SOUND_CLICK); //音を鳴らす }else{ PlaySound(SOUND_LOW_BEEP); //音を鳴らす } Wait(50); until(Message()==ARMDOWN); SendMessage(5); OnFwd(OUT_AC); //アームを上げる Wait(150); ClearTimer(0); ClearMessage(); while((Message() != 6)||(FastTimer(0)<SENDTIME)){ SendMessage(GOBACK); } if(Message() == 6){ PlaySound(SOUND_CLICK); //音を鳴らす }else{ PlaySound(SOUND_LOW_BEEP); //音を鳴らす } Wait(50); until(Message()==ARMUP); SendMessage(7); OnRev(OUT_AC); //アームを下げて積み重ねる Wait(150); } }
一番の反省として、プログラムが自分たちが作ったように機能しなかったことである。通信機能を使うことが出来ず本番はプログラムをすべて書いて最後に確認してからミスしているところを直していったのでこのようになったと思う。音のなるプログラムを使って1行ずつ確認していくべきだった。 だが、課題1の時と比べて成長したと思うところもある。ロボットもプログラムも前回に比べてよいものができた。前回の反省も生かすことが出来た。 授業を終えてプログラムについて少しは理解できたかなと思う。今後もロボティクス入門ゼミで学んだことを生かして頑張りたい。