このページの著者である。趣味はネトゲーで、AVAをしている。別名はさとTである。
8割方のロボットを作ってくれた、頼れる人でいつも鋭い指摘をしてくれる
4人の中で最も真っ当な性格を持ち主を持っていて、非常に真面目である。
教職とっていて大変そうであまり来なかったイメージだったが、来てくれた時はいつも励ましてくれて素晴らしい性格の持ち主だ。
フィールドは課題1で使用した、缶をつなぎ合わせたものにする。
START地点から始まり、缶を積み上げて行きGOAL地点で積み上げた缶を置く。
途中でうまく動かなくなった場合、一回限りやり直しができる。
得点方法は、n段目の空き缶の点数を5n点として、すべての空き缶の点数を合計したものを点数とする。
ロボットは2つのロボットを合わせて合体型にすることに決めた。
理由は、分離型ではどちらかの駆動部のモーターを一つにする必要があるが、モーターひとつでは限界があると感じたからである。
ロボットはこのようになった。駆動部は三輪車にして、小回りが効くようになっている。黄色い円で示した部分は、ジャッキである。
ジャッキとアームに分けて説明する。
赤い丸で示した、タイヤ4つで缶をつかむのである。これで、缶をつかめるのかという不安がよぎったが、予想以上にモーターの出力が強く杞憂に終わった。しかし、これは欠点がある。アームを掴むと重心が変わり、不安定になってしまうのである。
これを解決するために、タイヤをゴムにした。こうすることによって、重心が移ることがなく、安定するのである。
缶はこの「爽快ビタミン」が非常に良く課題1で反応するためにこれを使った。
このロボットの最も特徴的なジャッキの仕組みを説明する。ジャッキには、モーター部分と駆動部分がある。
まずは、モーター部分を説明する。
モーター部分はこのようになっている。
駆動部は非常に重いために、モーター二つとウォームギアが二つ必要としている。モーターが回ることによって、ウォームギアが回り、駆動部のギアを回す仕組みになっているのである
次にアームの部分である。駆動部である。駆動部とギアの部分はこのようになっている。
緑色の円で示したところが、ギアの上に付けて、動くことによって駆動部が上下運動することを可能にしているのである。
プログラムは、全部で9個ある缶を2個と2個の二つのタワーにするプログラミングを作ることにした。
なぜ、ここまでハードルを低くしたかというとロボットを作るということの難しさを目の当たりにしたからである。
しかし、結局一個も運べなかった。
つまり、最高点数は
(5+10)+(5+10)=30点のプログラミングである。
缶を積むルートは、左半分のみ走行するようにプログラミングをした。
結局上手く動かなかったために、ほぼ空想上のプログラムになってしまっている。また、時間がなかったために非常に効率が悪く長いプログラムになってしまっている。
#define kurot 37 //黒線の中央 #define kurok 42 //黒線の境界 #define kurog 45 //ギリギリ黒線を認識する部分 #define shiro 47 //白色の部分 #define hi 5 //大きい力を出力する #define low 2 //小さい力を出力する #define sh SetPower(OUT_AC, hi); //ACに大きい力を出力する #define sl SetPower(OUT_AC,low); //ACに小さい力を出力する #define slh SetPower(OUT_A,low); SetPower(OUT_C,hi); //Aには小さい力、Cには大きい力を出力する #define shl SetPower(OUT_A,hi); SetPower(OUT_C,low); //Aには大きい力、Cには小さい力を出力する #define sss SetPower(OUT_A,1);SetPower(OUT_C,1); //ACに最も小さい力を出力する #define mae sh OnFwd(OUT_AC); //前へ進む #define ushiro OnRev(OUT_AC); //後ろへ進む #define migi0 sl; OnFwd(OUT_C); Off(OUT_A); //右へ曲がる #define migi1 sl; OnFwd(OUT_C); OnRev(OUT_A); //右旋回 #define hidari0 sl; Off(OUT_C); OnFwd(OUT_A); //左へ曲がる #define hidari1 sl; OnRev(OUT_C); OnFwd(OUT_A); //左旋回 #define STEP 1 //whieの周期を1で回す #define nMAX 5 //hidar1を五回したら交差点と判断する #define yasumi Off(OUT_AC); Wait(100); //1秒間小休止 #define cross 25 //交差点を渡る時間 #define cross_line sl; OnFwd(OUT_AC); Wait(cross); yasumi; //交差点を渡るための定義付け #define kousin 5 //わずかに後ろに下がるためのメッセージ #define pdown 6 //完全にアームを下げるためのメッセージ #define zensin 7 //わずかに前進する #define kyatti 8 //缶をキャッチする #define anoraitore 10 //一つ目の交差点を通るためのメッセージ #define kankan 11 //上にあげた2段目の缶を一段目の缶までの高さまで下げるためのメッセージ #define bnoraitore 12 //二つ目の交差点を通るためのメッセージ #define cnoraitore 13 //出発点のT字路を通るためのメッセージ #define bniraitore 14 //2回目の二つの交差点を通るためのメッセージ #define kanhanasu 15 //缶を離すためのメッセージ #define tyoikousin 16 //少しだけ後進するためのメッセージ
int p=0; //hidari1を通る回数でnMAX以上になると、交差点と判断する int n=0; //交差点を通った回数 sub hidarikan () { //一つ目の缶を通るまでライントレース
SetSensor(SENSOR_1,SENSOR_LIGHT); //ポート1を光センサーにする SetSensor(SENSOR_3,SENSOR_LIGHT); //ポート3を光センサーにする while(SENSOR_1 > 55){ //缶用の光センサーが缶が感知するまでライントレース if (SENSOR_1 < kurot){ //光センサーが黒線の中央を感知 hidari1; //左旋回する p++; //左旋回した回数 } else { if(SENSOR_1 < kurok){ //光センサーが黒線の境界を感知 hidari0; //左に曲がる } else if (SENSOR_1 < kurog){ //光センサーが黒線のギリギリの場所を感知 mae; //前へ進む } else if (SENSOR_1 < shiro){ //光センサーが白を感知 migi0; 右へ曲がる } else { //それ以外の時 migi1; //右旋回する } p=0; //左旋回した回数のカウントを0にする } Wait(STEP); //STEP秒間で周期を回す } yasumi; //小休止 migi1; //右旋回 Wait(nMAX*STEP*2); //右旋回する時間を調整する cross_line; //交差点を渡る n++; //交差点を渡った回数をカウントする p=0; //左旋回した回数のカウントを0にする }
sub hidaria () { //交差点を2回渡るまでのライントレースをする SetSensor(SENSOR_1,SENSOR_LIGHT); SetSensor(SENSOR_3,SENSOR_LIGHT);
while(n < 2){ while(p < nMAX){ if (SENSOR_1 < kurot){ hidari1; p++; } else { if(SENSOR_1 < kurok){ hidari0; } else if (SENSOR_1 < kurog){ mae; } else if (SENSOR_1 < shiro){ migi0; } else { migi1; } p=0; } Wait(STEP); } yasumi; migi1; Wait(nMAX*STEP*2); cross_line; n++; p=0; } }
sub hidarib () { //交差点を3回渡るまでのライントレースをする SetSensor(SENSOR_1,SENSOR_LIGHT); SetSensor(SENSOR_3,SENSOR_LIGHT);
while(n < 3){ while(p < nMAX){ if (SENSOR_1 < kurot){ hidari1; p++; } else { if(SENSOR_1 < kurok){ hidari0; } else if (SENSOR_1 < kurog){ mae; } else if (SENSOR_1 < shiro){ migi0; } else { migi1; } p=0; } Wait(STEP); } yasumi; migi1; Wait(nMAX*STEP*2); cross_line; n++; p=0; } }
sub hidaric () { //交差点を4回渡るまでのライントレースをする SetSensor(SENSOR_1,SENSOR_LIGHT); SetSensor(SENSOR_3,SENSOR_LIGHT);
while(n < 4){ while(p < nMAX){ if (SENSOR_1 < kurot){ hidari1; p++; } else { if(SENSOR_1 < kurok){ hidari0; } else if (SENSOR_1 < kurog){ mae; } else if (SENSOR_1 < shiro){ migi0; } else { migi1; } p=0; } Wait(STEP); } yasumi; migi1; Wait(nMAX*STEP*2); cross_line; n++; p=0; } }
sub hidarid () { //交差点を7回渡るまでライントレース SetSensor(SENSOR_1,SENSOR_LIGHT); SetSensor(SENSOR_3,SENSOR_LIGHT);
while(n < 7){ while(p < nMAX){ if (SENSOR_1 < kurot){ hidari1; p++; } else { if(SENSOR_1 < kurok){ hidari0; } else if (SENSOR_1 < kurog){ mae; } else if (SENSOR_1 < shiro){ migi0; } else { migi1; } p=0; } Wait(STEP); } yasumi; migi1; Wait(nMAX*STEP*2); cross_line; n++; p=0; } }
task main () {
int p=0; //hidari1を通る回数でnMAX以上になると、交差点と判断する int n=0; //交差点を通った回数 int k=0; //メッセージを送った回数 migi0;until(SENSOR_1 < 45); Off(OUT_AC); 黒線に当たるまで、右に曲がる hidarikan(); //缶を感知するまで、ライントレース ClearMessage(); //余分に入っていたメッセージをリセットする SendMessage(kyatti); //缶をつかむためのメッセージを送る Wait(10); //0.1秒間待つ ClearMessage(); //メッセージをリセットする while(k < 1){ //一つ目のメッセージを受信するまで待機 until(Message() == anoraitore); hidaria(); //一つ目の交差点を渡るまでライントレース k++; //メッセージ送った回数をカウントする } hidarikan(); //2個目の缶を感知するまでライントレース ClearMessage(); //メッセージをリセット SendMessage(kankan); //2段目の缶を一段目の缶の高さまで Wait(10); //0.1秒間待つ ClearMessage(); //メッセージをリセットする while(k < 2){ //2つ目のメッセージを受信するまで待機 until(Message() == kousin); OnRev(OUT_AC); //わずかに後進する Wait(10); Off(OUT_AC); k++; //メッセージを送った回数をカウントする } ClearMessage(); SendMessage(pdown); Wait(10); ClearMessage(); while(k < 3){ //3つ目のメッセージを受信するまで待機 until(Message() == zensin); OnFwd(OUT_AC); Wait(10); Off(OUT_AC); k++; } ClearMessage(); SendMessage(kyatti); Wait(10); ClearMessage(); while(k < 4){ //4つ目のメッセージを受信するまで待機 until(Message() == bnoraitore); hidarib();
●GOAL地点に缶を置くまでのプログラム(ここから)
hidari1; Wait(50); OnFwd(OUT_AC); Wait(25); OnRev(OUT_AC); Wait(50); Off(OUT_AC); migi0; Wait(50); migi1;until(SENSOR_1 <45); Off(OUT_AC);
●GOAL地点に缶を置くまでのプログラム(ここまで)
hidarikan(); k++; } ClearMessage(); SendMessage(kyatti); Wait(10); ClearMessage(); while(k < 5){ //5回目のメッセージを受信するまで待機 until(Message() == cnoraitore); hidaric(); hidarikan(); k++; } ClearMessage(); SendMessage(kankan); Wait(10); ClearMessage(); while(k < 6){ //6回目のメッセージを受信するまで待機 until(Message() == kousin); OnRev(OUT_AC); Wait(10); Off(OUT_AC); k++; } ClearMessage(); SendMessage(pdown); Wait(10); ClearMessage(); while(k < 7){ //7回目のメッセージを受信するまで待機 until(Message() == zensin); OnFwd(OUT_AC); Wait(10); Off(OUT_AC); k++; } ClearMessage(); SendMessage(kyatti); Wait(10); ClearMessage(); while(k < 8){ //8回目のメッセージを受信するまで待機 until(Message() == bniraitore); hidarid(); hidari0; Wait(10); OnFwd(OUT_AC); Wait(15); k++; } ClearMessage(); SendMessage(kanhanasu); Wait(10); ClearMessage(); while(k < 9){ //9回目のメッセージを受信するまで待機 until(Message() == tyoikousin); //少し後進する OnRev(OUT_AC); Wait(100); Off(OUT_AC); k++; } }
#define hi 1 //高い力を出力 #define low 1 //低い力を出力 #define lift_up OnFwd(OUT_AB); //ジャッキを上げる #define lift_down OnRev(OUT_AB); //ジャッキを下げる #define tukamu OnRev(OUT_C); //アームをつかむ #define release OnFwd(OUT_C); //アームを離す #define MOVE_TIMEA 280 //ジャッキを上げる時間 #define MOVE_TIMEB 140 //ジャッキを下げる時間 #define MOVE_TIMEC 30 //2段目の缶が1段目の缶の高さまで下げる時間 #define MOVE_TIMED 250 //一段分の缶の高さを下げる時間 #define kousin 5 #define pdown 6 #define zensin 7 #define kyatti 8 #define anoraitore 10 #define kankan 11 #define bnoraitore 12 #define cnoraitore 13 #define bniraitore 14 #define kanhanasu 15 #define tyoikousin 16
int k=0;
task main() { ClearMessage(); //メッセージをリセット while(k < 1){ //一つ目のメッセージを受信されるまで待機 until(Message() == kyatti); //缶をキャッチするメッセージを受信する tukamu; //缶をつかむ Wait(50); lift_up; //缶を上げる Wait(300); k++; //kの回数をカウント } ClearMessage(); //メッセージをリセット SendMessage(anoraitore); Wait(10); while(k < 2){ //二つ目のメッセージを受信されるまで待機 ClearMessage(); //メッセージをリセット until(Message() == kankan); lift_down; //アームを下げる Wait(MOVE_TIMEC); Off(OUT_AB); release; //缶を離す Wait(50); Off(OUT_C); k++; } ClearMessage(); SendMessage(kousin); Wait(10); ClearMessage(); while(k < 3){ //3つ目のメッセージを受信するまで待機 until(Message() == pdown); lift_down; Wait(MOVE_TIMED); Off(OUT_AB); k++; } ClearMessage(); SendMessage(zensin); Wait(10); ClearMessage(); while(k < 4){ //4つ目のメッセージを受信するまで待機 until(Message() == kyatti); tukamu; Wait(50); k++; } ClearMessage(); SendMessage(bnoraitore); Wait(10); ClearMessage(); while(k < 5){ //5つ目のメッセージを受信するまで待機 until(Message() == kyatti); tukamu; Wait(50); lift_up; Wait(MOVE_TIMEA); k++; } ClearMessage(); SendMessage(cnoraitore); //出発地点にT字路まで、 Wait(10); ClearMessage(); while(k < 6){ //6つ目のメッセージを受信するまで待機 until(Message() == kankan); lift_down; Wait(MOVE_TIMEC); release; //缶を離す Wait(50); k++; } ClearMessage(); SendMessage(kousin); //わずかに後進 Wait(10); ClearMessage(); while(k < 7){ //7つ目のメッセージを受信するまで待機 until(Message() == pdown); //完全に下がる lift_down; Wait(MOVE_TIMED); Off(OUT_AB); k++; } ClearMessage(); SendMessage(zensin); //わずかに前進 Wait(10); ClearMessage(); while(k < 8){ //8つ目のメッセージを受信するまで待機 until(Message() == kyatti); tukamu; Wait(50); k++; } ClearMessage(); SendMessage(bniraitore); //ゴール地点までライントレース ClearMessage(); while(k < 9){ //9つ目のメッセージを受信するまで待機 until(Message() == kanhanasu); //缶を離す release; Wait(50); k++; } ClearMessage(); SendMessage(tyoikousin); //少し後進する Wait(10); Off(OUT_ABC); }
結果は、0点で最下位になってしまった。
また、ライントレースができなかったため、ジャッキの仕組みのみを実演するようになってしまった。
ほぼ全ての反省点がもう少し時間がかければ解決できたであろうと感じた
反省点として挙げられるのは、2点である。
・ロボットが脆い
自分が扱い方が悪いというのもあるが、少し強く押したりしてしまったら壊れてしまったりした。
もっと頑丈にするべきだったと感じた。
・ライントレース時に横に揺れる
ライントレースをする時に、横に揺れて不安定な動きをしてしていた。光センサーの位置をを高くしたり、閾値を調整すれば良かったと推測する。
・プログラムが不完全
プログラムを入れる事ができたのが、発表の直前でありプログラムの不備を確認することができなかった。そのために、ライントレースすらできなかった。もう少し時間が欲しいと感じた。
課題1は自分の基準では良くできたと思っている。
しかし、課題2では全くできず、ライントレースすらできなかった。なので、チームの他の3人に多大な迷惑した事は本当に申し訳ないと感じている。しかし、初めていわゆるロボットというものを作ることができて、非常に充実した授業だった。