[[2018a/Member]]
#contents
*課題 [#kde01d96]
空き缶運搬ロボット
空き缶を分別し、特定の場所に運ぶ。
2種類の空き缶(Aタイプ,Bタイプ)をそれぞれ3個ずつ用意し、円XにABA、円YにBABとなるように3段ずつ積み上げる。
円X内にBの缶、円Y内にAの缶を運ぶ。積み上げると得点が上がる。
&ref(2018a/Member/yamada/Mission2/2018a-mission2.png,60%,走行するコース);
*ロボット本体 [#k244554e]
&ref(2018a/Member/yamada/Mission3/IMG_0647.JPG,30%,ロボット本体 側面から);
側面から見た様子。
前方に缶をつかむためのアームと、ア−ムを上げ下げする部分があり、重い。
バランスをとるために後方に知能ブロックを二つ取り付けた。
スムーズに動かすために前方にも後方にも車輪を付けたが、
逆に動きにくくしているとの指摘があった。
&ref(2018a/Member/yamada/Mission3/IMG_0648.JPG,30%,ロボット本体 上から);
上から見た様子。
&ref(2018a/Member/yamada/Mission3/IMG_0649.JPG,30%,ロボット本体 正面から);
正面から見た様子。
&ref(2018a/Member/yamada/Mission3/IMG_0650.JPG,30%,ロボット本体 後ろから);
後ろから見た様子。
&ref(2018a/Member/yamada/Mission3/IMG_0651.JPG,30%,缶をつかむアーム);
缶をつかむアーム。
モーターの回転部中心に軸がささる。
二つの歯車をかみ合わせることで、
一つのモーターの回転のみで開閉、つまり缶をつかんだり放したりできるようになっている。
&ref(2018a/Member/yamada/Mission3/IMG_0655.JPG,30%,アームを上げ下げする部分 正面から);
アームを上げ下げする部分。正面から見た様子。
&ref(2018a/Member/yamada/Mission3/IMG_0654.JPG,30%,アームを上げ下げする部分 側面から);
アームを上げ下げする部分。
側面から見た様子。
機関車のように、アームにつながった部分がモーターの回転により上下する。
上下させる際、途中で引っかかってしまうことがあった。
モーターとアームをつなぐ部分を短くした方が良いと指摘があった。
*プログラム [#m8863906]
当初はライントレースにより缶のところまで移動する予定であったが、トラブルの発生などにより断念。
ロボコン時のプログラムは以下のようになった。
��A地点からまっすぐ進みY地点へ移動。
��Y地点の3段になった缶の、2段目の部分をつかみ、下ろす。
�2爾蹐靴心未両紊砲里辰討い心未鬚弔�み、Y地点にある缶の上にのせる。
�き�によりできた2段積みの缶をX地点へ運ぶ。
��X地点にある3段積みの缶の塔をなぎ倒し、運んできた2段積みの缶をX地点に置く。
**スレーブのプログラム [#n36c5d6b]
プログラムの作成過程でトラブルが発生し、NXTに転送してあったスレーブのプログラムは見られなくなってしまった。
以下は、プログラムの作成を担当してくれたメンバーが再現してくれたもの。
モーターAがアームの開閉、モーターBとCがアームの上下を担当。
-アームを開く・缶を放す
task main(){ OnFwd(OUT_A,1c0); Wait(500); Off(OUT_A); }
-アームを閉じる・缶をつかむ
task main(){
OnRev(OUT_A,20);
Wait(1000);
}
-アームを上げる
task main(){
OnRev(OUT_BC,30);
OnRev(OUT_A,10);
Wait(8000);
}
-缶をつかみ続ける
task main(){
OnFwd(OUT_A,20);
Wait(1000);
Off(OUT_A);
}
上記�↓�の、
「2段目の缶(上には3段目の缶がのっている)をつかんだ後、持ち上げて横にスライドし、その後下ろす。」
「下ろした缶の上にのっていた缶をつかんだ後、持ち上げて横にスライドし、元の位置にある缶の上に下ろす。」
という過程で缶がずり落ちないようにつかみ続けるプログラム。
-アームを下ろす
task main(){
OnFwd(OUT_BC,20);
Wait(600);
Off(OUT_BC);
}
**マスターのプログラム [#g5db9432]
タイヤを動かし機体を移動させることと、スレーブにアームの上げ下げや開閉を指示することを担当。
***ライントレースしようとしたがうまくいかなかったプログラム [#p65c8795]
途中まで成功していたプログラムであったが、変更したところうまくいかなくなってしまった。
課題2のプログラムを元にライントレースするプログラムを作成。
どの段階を実行しているか確認するために要所要所で音を発するようにプログラム。
それらとアームの動作を組み合わせた。
-定数の定義
#define CONN 1//スレーブの番号を割り振り
#define AGERU RemoteStartProgram(CONN,"ageru.rxe");Wait(4500); //アームの上げるのを定義
#define SAGERU RemoteStartProgram(CONN,"sageru.rxe");Wait(3000); //アームの下げるのを定義
#define TUKAMU RemoteStartProgram(CONN,"tukamu.rxe");Wait(3500); //アームで掴むのを定義
#define HANASU RemoteStartProgram(CONN,"hanasu.rxe");Wait(3000); //アームで放すのを定義
#define MODOSU RemoteStartProgram(CONN,"modosu.rxe");Wait(3000); //アームを開きもとに戻す
#define KUZUSU
TUKAMU;AGERU;OnRev(OUT_BC,10);Wait(1000);Off(OUT_BC);OnFwd(OUT_B,15);OnRev(OUT_C,15);Wait(1500);Off(OUT_BC);OnFwd(OUT_BC,10);Wait(1000);Off(OUT_BC);Wait(3000);SAGERU;HANASU;TUKAMU;AGERU;OnRev(OUT_BC,10);Wait(1000);Off(OUT_BC);OnFwd(OUT_C,15);OnRev(OUT_B,15);Wait(1600);Off(OUT_BC);OnFwd(OUT_BC,10);Wait(1300);Off(OUT_BC);Wait(1000);SAGERU;HANASU;
#define BLACK 40
#define LITTLE_BLACK 47
#define LITTLE_WHITE 53
#define WHITE 65
#define LEFT OnFwd(OUT_B,30);OnRev(OUT_C,30);Wait(1);Off(OUT_BC);
#define LITTLE_LEFT OnFwd(OUT_B,35);OnFwd(OUT_C,20);Wait(1);Off(OUT_BC);
#define LITTLE_RIGHT OnFwd(OUT_B,20);OnFwd(OUT_C,35);Wait(1);Off(OUT_BC);
#define RIGHT OnFwd(OUT_C,30);OnRev(OUT_B,30);Wait(1);Off(OUT_BC);
#define FRONT OnFwd(OUT_BC,25);Wait(1);Off(OUT_AC);
#define LINE_LEFT if (SENSOR_1 < BLACK) {LEFT;KAZU += 3;} else if (SENSOR_1 <
LITTLE_BLACK) {LITTLE_LEFT;KAZU += 1;} else if (SENSOR_1 > WHITE) {RIGHT;KAZU -= 1;} else
if (SENSOR_1 > LITTLE_WHITE) {LITTLE_RIGHT;KAZU -= 3;} else {FRONT;KAZU *= 0;}
#define LINE_RIGHT if (SENSOR_1 < BLACK) {RIGHT;KAZU += 3;} else if (SENSOR_1 <
LITTLE_BLACK) {LITTLE_RIGHT;KAZU += 1;} else if (SENSOR_1 > WHITE) {LEFT;KAZU -= 1;}else
if (SENSOR_1 > LITTLE_WHITE) {LITTLE_LEFT;KAZU -= 3;} else {FRONT;KAZU *= 0;}
アームの動きを定義。
ライントレースのための明るさの閾値を定義。
明るさごとの走行の仕方を定義。
線の右側、左側それぞれでのライントレースの仕方を定義。
-task main
task main() {
SetSensorLight(S1); //光センサを定義 int KAZU=0; int n = 0; long t0 = CurrentTick();
RemotePlayTone(1,440,1000);Wait(1500); //最初に音を鳴らす
MODOSU; //最初に念のため開いておく
while(n < 1){
if (SENSOR_1 < BLACK) {OnFwd(OUT_C,25);OnFwd(OUT_B,20);Wait(700);Off(OUT_BC);n++;Off(OUT_BC);Wait(1);}
else {OnFwd(OUT_BC,20);Wait(1);Off(OUT_BC);}
}
n = 0; //黒を感知するまで進む//線を超えるために進む
while(n < 1){
if (SENSOR_1 < LITTLE_WHITE)
{OnFwd(OUT_C,35);OnFwd(OUT_B,20);Wait(100);Off(OUT_BC);n++;Off(OUT_BC);Wait(1);}
else {OnFwd(OUT_B,40);OnFwd(OUT_C,20);Wait(1);Off(OUT_BC);}
}
n = 0; //黒を感知するまで曲がる
repeat(2000){LINE_RIGHT;};KAZU *= 0; while(KAZU < 300){LINE_RIGHT;};
PlaySound(SOUND_DOUBLE_BEEP); //十字の交差点を感知
OnFwd(OUT_C,30);OnRev(OUT_B,30);Wait(1200); //右に曲がる
OnFwd(OUT_BC,15);Wait(300);Off(OUT_BC);
repeat(2000){LINE_RIGHT;};KAZU *= 0; while(KAZU < 200){LINE_RIGHT;};
PlaySound(SOUND_DOUBLE_BEEP); //円との交差点を感知
KUZUSU; //缶を崩す
OnFwd(OUT_BC,15);Wait(200);Off(OUT_BC); OnRev(OUT_BC,15);Wait(200);Off(OUT_BC);
OnFwd(OUT_C,15);OnRev(OUT_B,30);Wait(200);Off(OUT_BC);
OnFwd(OUT_B,15);OnRev(OUT_C,15);Wait(200);Off(OUT_BC); //ぐちゃぐちゃやって整える
Wait(1000);
SAGERU;TUKAMU; //引きずるために掴む
Wait(2000);
OnFwd(OUT_B,40);OnFwd(OUT_C,30);Wait(3000);Off(OUT_BC); //円を超えるために進む
repeat(3000){LINE_RIGHT};KAZU *= 0; while(KAZU < 200){LINE_RIGHT};
PlaySound(SOUND_DOUBLE_BEEP); //十字の交差点を感知
/* OnFwd(OUT_C,20);OnRev(OUT_B,20);//右に曲がる Wait(2500); Off(OUT_BC);
repeat(1500){LINE_RIGHT}; KAZU *= 0; while(KAZU < 100){LINE_RIGHT};
PlaySound(SOUND_DOUBLE_BEEP);//十字の交差点を感知
while(n < 1){
if (SENSOR_1 < BLACK){OnFwd(OUT_BC,20);Wait(1);Off(OUT_BC);}
else{n++;Off(OUT_BC);Wait(1);}
}n = 0; //白を感知するまで進む OnFwd(OUT_BC,25); Wait(700); Off(OUT_BC); MODOSU;*/
/*TUKAMU;AGERU; OnRev(OUT_BC,20);Wait(2000);Off(OUT_BC); OnFwd(OUT_B,30);OnRev(OUT_C,30);
Wait(1000); Off(OUT_BC); OnFwd(OUT_BC,20);Wait(2000);Off(OUT_BC); SAGERU;HANASU;
TUKAMU;AGERU; OnRev(OUT_BC,20);Wait(2000);Off(OUT_BC); OnFwd(OUT_C,30);OnRev(OUT_B,30);
Wait(1000); Off(OUT_BC); OnFwd(OUT_BC,20);Wait(2000);Off(OUT_BC); SAGERU;HANASU;MODOSU;*/
/*repeat(1000){LINE_RIGHT}; KAZU *= 0; while(KAZU < 100){LINE_RIGHT};
PlaySound(SOUND_DOUBLE_BEEP);//円との交差点を感知
}
スタート時にアームを開き忘れても困らないよう、最初にアームを開くプログラムが入っている。
A地点からスタート。
A地点を囲う枠線を越え、ラインとレースするために黒線の端へ移動。
A地点を囲う枠線を越え、ライントレースするために黒線の端へ移動。
B地点で右折。Yの円に到着後、3段積みの缶を種類ごとに分けて2段積みにした方をX地点へ運ぶ。
X地点にある3段積みの缶の塔を倒し、空いたスペースに運んできた缶を置く。
***ロボコン直前に突貫で作成したプログラム [#m33868d5]
先述した通りの動きをするようにプログラムした。
ロボコン本番では失敗。
スタート地点での機体の置き方次第で成功するか否か決まってしまうプログラムであった。
-定数の定義
#define CONN 1//スレーブの番号を割り振り
#define AGERU RemoteStartProgram(CONN,"ageru.rxe");Wait(4500); //アームの上げるのを定義
#define SAGERU RemoteStartProgram(CONN,"sageru.rxe");Wait(3000); //アームの下げるのを定義
#define TUKAMU RemoteStartProgram(CONN,"tukamu.rxe");Wait(3500); //アームで掴むのを定義
#define HANASU RemoteStartProgram(CONN,"hanasu.rxe");Wait(3000); //アームで放すのを定義
#define MODOSU RemoteStartProgram(CONN,"modosu.rxe");Wait(3000); //アームを開きもとに戻す
#define KUZUSU
TUKAMU;AGERU;OnRev(OUT_BC,30);Wait(1000);Off(OUT_BC);OnFwd(OUT_B,30);OnRev(OUT_C,30);Wait(1500);Off(OUT_BC);OnFwd(OUT_BC,30);Wait(1000);Off(OUT_BC);Wait(3000);SAGERU;HANASU;TUKAMU;AGERU;OnRev(OUT_BC,30);Wait(1000);Off(OUT_BC);OnFwd(OUT_C,30);OnRev(OUT_B,30);Wait(2000);Off(OUT_BC);OnFwd(OUT_BC,30);Wait(1300);Off(OUT_BC);Wait(1000);SAGERU;
-task main
task main() { MODOSU; RemotePlayTone(1,440,1000);Wait(1500); //最初に音を鳴らす
OnFwd(OUT_BC,30); Wait(4000); Off(OUT_BC);
KUZUSU; //缶を崩す
OnFwd(OUT_BC,15);Wait(200);Off(OUT_BC); OnRev(OUT_BC,15);Wait(200);Off(OUT_BC);
OnFwd(OUT_C,15);OnRev(OUT_B,30);Wait(200);Off(OUT_BC);
OnFwd(OUT_B,15);OnRev(OUT_C,15);Wait(200);Off(OUT_BC); //ぐちゃぐちゃやって整える
SAGERU;TUKAMU; //引きずるために掴む
OnFwd(OUT_B,30); OnFwd(OUT_C,35); Wait(4000); Off(OUT_BC);
OnFwd(OUT_C,30); Wait(500); Off(OUT_C);
HANASU; MODOSU; }
*反省 [#of19b2db]
-チームとして
途中まで成功していたプログラムや機体を多少変更したところ、うまくいかなくなった。
時間が足りず、しっかりと原因を考えることができなかった。
しかし期末テストやレポートなどで切羽詰まった中で、できる限り時間をつぎ込んだと思う。
-個人として
ロボットの作成、プログラムの作成、どちらでも役に立てなかった。
創造力と工夫する力が自分には不足していると分かった。
さらにロボコン前日は別の用事があり作業に参加できず、メンバーに迷惑をかけた。
持てる時間を目一杯使って作成に取り組んでくれたメンバーには感謝しかない。