*概要 [#n8833406] #contents *課題 [#x59ffb6b] 以下のURLを参照 http://yakushi.shinshu-u.ac.jp/robotics/?2014a%2FMission2 4人でグループを組み、ロボットの組み立て、プログラムを組む~ 私は主にプログラムを担当した~ *ロボット本体 [#cddf467d] このロボットは 「つかむ」、「持ち上げる」または、持ち上げている状態から、「降ろす」、「はなす」を一連の流れの中で行うことのできるアームを搭載している~ 真上~ &ref(IMG_0481.JPG);~ 右側面~ &ref(IMG_0487.JPG);~ 左側面~ &ref(IMG_0489.JPG);~ 真後ろ~ &ref(IMG_0488.JPG);~ 正面(アーム解放時)~ &ref(IMG_0485.JPG);~ &ref(IMG_0486.JPG);~ 正面(アーム閉じ)~ &ref(IMG_0490.JPG);~ *攻略 [#f3e66b15] 今回の課題もパートごとに分け、そのパートにかかる時間を調節してクリアを目指す~ ABCの紙コップにはあらかじめ、黒、鉛筆色(グレー)、白(何も塗らない)、の三色をそれぞれの紙コップの側面全体に塗っておく。~ **攻略1:邪魔な紙コップから片づける [#s2273192] Aの紙コップは紙と紙をつなぐ線上にあり、道をふさぐようにしておいてある。~ B,Cの紙コップから運ぶ場合、Aの紙コップをライントレース中にどけて、見失う可能性があるので、Aの紙コップから運ぶ~ ***経路 [#gfbecd1e] スタート地点から、次の経路でAのコップへ向かい、コップをつかむ~ &ref(攻略1.png);~ ***判別 [#pb56fcd9] ロボットの正面についている赤外線レーザーを使い、紙コップを判別する。~ 1,2,3の紙コップへ向かう時、ライントレースはそれぞれのルートに適したプログラムを組んだ。~ ***A地点へ戻る [#m3337a92] 以後、このA地点を基準にして動く **攻略2:ライントレースをあまりせずにB、Cの紙コップを取りに行く [#a2362c44] ライントレースを全くせずにやると、どこかでズレが生じた時、紙コップを取るのは不可能になる。~ ライントレースをするのが難しい(交差点などの)経路を通るとすると、紙コップをとれる可能性が下がる~ よって、簡単なライントレースで、簡単に目的地へ行ける経路を通る~ ***Bの紙コップへ向かう経路 [#v2bd7f3c] Bには以下の経路を右ライントレースで向かう~ &ref(攻略2.png);~ 円軌道上を走行中、ライントレースを中断し、Bの紙コップへの最短経路へ直進し、再度ライントレースを始めてBのコップへ近づく~ ***Cの紙コップへ向かう経路 [#u53ba974] Cには以下の経路で向かう~ &ref(攻略3.png);~ 円軌道上を走行中、ライントレースを中断し、Cの紙コップ手前の線上に直進し、再度ライントレースを始めてCのコップへ近づく~ B,Cの紙コップは、Aの紙コップ同様に、判別後、紙コップを運ぶ~ *プログラム [#q2edb03f] **親機側 [#w14b2d94] ***定義 [#y399b3d1] #define s1 50 //高速 #define s2 30 //低速 #define OnRL(x,y) OnFwd(OUT_A,x); OnFwd(OUT_C,y); #define go OnFwdSync(OUT_AC,s2,0); //直進 #define left1 OnRL(-s2,s2); //左旋回 #define left0 OnRL(0,s2); //左折 #define right0 OnRL(s2,0); //右折 #define right1 OnRL(s2,-s2); //右旋回 #define step 1 #define nMAX 300 //nMAXを超えた時交差点と判断する #define short_break Off(OUT_AC); Wait(500); //小休憩 #define cross_line go;Wait(200);short_break; //交差点を渡る #define open 4 #define motiageru 1 #define tukamu 2 #define hanasu 3 #define time1 2000 //始めの旋回、ちょうど90°旋回できる時間、要設定 #define part2 15000 //Aを掴んでから1に置くまでの時間、要設定 #define part3 10000 //Aを掴んでから2に置くまでの時間、要設定 #define part4 15000 //Aを掴んでから3に置くまでの時間、要設定 #define song PlaySound(SOUND_CLICK);//音を鳴らす task main() { SetSensorLight(S2); //ライントレースをするライトセンサーを設置 SetSensorLight(S3); //紙コップを識別するためのライトセンサーを設置 ***Aの紙コップに向かい、紙コップをつかむ [#e9134272] go; Wait(4500); //4.5秒間直進 song; left1; //左に旋回 Wait(time1); //90度回転するまで続ける song; go; //直進 Wait(800); song; SendRemoteNumber(1,0,open); song; go; Wait(3000); SendRemoteNumber(1,0,tukamu); //つかむ song; int n1 = 0; //n1という関数を設置 ***前方についたセンサーで判別をする  [#n83610a3] int rooot = 0; //roootという関数を設置 ***前方についたセンサーで判別をする [#td10dee8] while(rooot = 0){ if(SENSOR_3 < 42){ rooot = 3;}//センサーが42未満の場合ルート3へ else if(SENSOR_3 < 50){ rooot = 2;}//センサーが50未満の場合ルート2へ else{ rooot = 1;}//それ以外の場合ルート1へ } Wait(1000); song; SendRemoteNumber(1,0,motiageru); //子機に送信しアームを稼働し持ち上げる song; go; //直進 Wait(1000); //1秒間続ける left0; //左折 Wait(1000); until(SENSOR_2 <45); //ライントレースするセンサーが45未満になるまで続ける long line = 0; //long lineという関数を設置 long t1 = CurrentTick(); //t1という関数を設置 ***rooot = 1 の時、ルート1へ向かう [#w38ab486] while(rooot = 1){ //roootが1の間ライントレースを続ける while(CurrentTick()-t1 <= part2){ //t1がpart2より大きくなるまでライントレースを続ける while (line < nMAX) { // lineがnMAX以上になるまで続ける if (SENSOR_2 < 40) { right1; line = line + 10; //交差点を抜けやすくする } else { if (SENSOR_2 < 45) { right0; } else if (SENSOR_2 < 55) { go; } else if (SENSOR_2 < 60) { left0; } else { left1; } line=0; } Wait(step); } short_break; right1; Wait(200); cross_line; line=0; } SendRemoteNumber(1,0,hanasu); rooot = 0; OnRev(OUT_AC,50); //A地点付近まで戻る Wait(500); left1; Wait(time1*2); go; Wait(4000); } ***rooot = 2 の時、ルート2へ向かう [#pde6c3a6] while(rooot = 2){ while(CurrentTick()-t1 <= part3){ if(SENSOR_2 < 40){ left1;} else if(SENSOR_2 < 45){ left0;} else if(SENSOR_2 < 55){ go;} else{ right0;} //右旋回はなし、2に向かうには交差点判断も必要ない Wait(step); } SendRemoteNumber(1,0,hanasu); rooot = 0; OnRev(OUT_AC,50); //A地点付近まで戻る Wait(500); left1; Wait(time1); go; until(SENSOR_2 < 45); } ***rooot = 3 の時、ルート3に向かう [#w75cf960] while(rooot = 3){ while(CurrentTick()-t1 <= part4){ //右ライントレース if(SENSOR_2 < 40){ right1;} else if(SENSOR_2 < 45){ right0;} else if(SENSOR_2 < 55){ go;} else if(SENSOR_2 < 60){ left0;} else{ left1;} } SendRemoteNumber(1,0,hanasu); rooot = 0; OnRev(OUT_AC,50); //A地点付近まで戻る Wait(500); right1; Wait(time1 + 300); go; Wait(3000); go; until(SENSOR_2 < 45); } ***2つ目を取りに行く [#y87a9563] 今回のロボコンではとにかく1つを運ぶことを目標にしていたため、2つ目以降のの紙コップを運ぶプログラムは作らなかった。 } **子機側 [#p84e429c] #define on 1 task main(){ int moterOn; while(true){ ReceiveRemoteNumber(0,true,moterOn); ***親機側から、アーム開く命令をもらった場合 [#ja1bb094] if(moterOn == 4){ OnFwd(OUT_B,50); Wait(300); Off(OUT_B); Wait(500); } ***親機側から、持ち上げる命令をもらった場合 [#u8d1edfd] else if(moterOn == 1){ OnRev(OUT_B,30); Wait(1000); Off(OUT_B); int moterOn =0; } ***親機側から、つかむ命令をもらった場合 [#udd81977] else if(moterOn == 2){ OnRev(OUT_B,30); Wait(1000); Off(OUT_B); int moterOn =0; } ***親機側から、はなす命令をもらった場合 [#v0b387d5] else if(moterOn == 3){ OnFwd(OUT_B,30); Wait(1000); Off(OUT_B); int moterOn = 0; } } } *反省と感想 [#ha266773] 前回同様、時間をフルに利用したプログラムとなった。~ スタート地点に機体を置き、誰がスイッチを入れてもクリアできるとは限らないという問題点が残ってしまった。~ 今思うと、コースは定められたものなので、どのように置いた場合でも、1つ目の紙コップをとれるように、スタート地点で修正をするプログラムを組めばよかったと思う。~ 作るのはすごく大変だが、より良いものになるはずである。~ ロボット本体に関しては、先生が見せてくれたアームを参考にしたが、NXC本体の取り付ける位置によっては全体のバランスが悪くなってしまい、うまく動かなくなった。~ 最終的には、このページで紹介したようになったが、まだ効率が悪い。~ 実際に開発の仕事をしている人は効率化をとにかく頑張っているのだと思うと、今使っている自分のパソコンなどの電子機器をはじめる、すべてのものの見方が変わってくる。~ 効率性、確実性、耐久性などすべてを考慮した最高のものは努力に努力を重ねて作られる、開発の大変さを感じた。~ 簡単なように見えた課題2だったが、取り掛かると難しかった。~ この講義でプログラムの基礎の基礎が学べたので、実家に置いてあるjavaの教本に手を出してみようかと思う。~