[[2018b/Member]] *課題 [#n1a83606] 青と赤のボールを運搬して、それぞれ所定の350ml缶の上に乗せる。 &ref(2018b/Member/kaito/Mission3/2018b-mission3.png,50%,コース); *移動順路 [#v802abff] &ref(2018b/Member/kaito/Mission3/2018b-mission3.png,50%,コース); X:スタート →G:ボールを掴む、上げる →G〜D:ライントレース →D:缶の位置と距離を測定 →赤ボールを乗せる →ラインに戻りIへ →青ボールを掴む、上げる →缶の位置と距離を測定 →青ボールを乗せる *自分が取り組んだこと [#y72c7bd7] ・ロボットの制作 ・ボールを掴む、離す、上げる、下ろす の動作のプログラミング。 ※上記以外のプログラミングについてはN5・N6メンバーのものを用いてレポートを作成しています。 *ロボットの構造 [#o4761a47] &ref(2018b/Member/kaito/Mission3/KIMG0103.jpg,50%,コース); ・前に突き出たクワガタのようなツノですくうようにしてボールを持つ ・超音波センサーの位置は低めにした。 &ref(2018b/Member/kaito/Mission3/KIMG0096_LI.jpg,30%,コース); ツノの開閉の動きに繋げられるように歯車が工夫されています。 &ref(2018b/Member/kaito/Mission3/KIMG0101.jpg,50%,コース); 手ではなく、ツノで挟むようにすることでより広範囲のものをつかむことができる *プログラミング [#lfb58aa8] **ボールを置くプログラミング [#o2e6d9f8] #define LOST OnFwd(OUT_C,15);Wait(685);Off(OUT_C); //手離す task main() { //ボールを持って腕は上がっている状態 LOST } **ボールを掴むプログラミング [#r1ca68a6] #define UP OnFwd(OUT_B,20);Wait(4750);Off(OUT_BC); //腕上げ #define DOWN OnRev(OUT_B,20);Wait(2600);Off(OUT_BC); //腕下げ #define CATCH OnRev(OUT_C,15);Wait(725);Off(OUT_BC); //手掴み task main() { DOWN CATCH UP } **課題をこなすプログラミング [#zdc14d98] #define turn_l1 OnFwd(OUT_B,33);OnRev(OUT_C,33); //左旋回 #define turn_r1 OnFwd(OUT_C,33);OnRev(OUT_B,33); //右旋回 #define turn_l0 OnFwd(OUT_B,30);Off(OUT_C); //左折 #define turn_r0 Off(OUT_B);OnFwd(OUT_C,30); //右折 #define go_s OnFwd(OUT_BC,30); //直進 #define stoop Off(OUT_BC); //止まる #define speed 70 #define speed_s 50 #define CONN 1 const float diameter=5.54; const float track=10.35; const float pi=3.1415; void fwdDist(float d) { long angle; angle= d/(diameter*pi)*360.0; RotateMotorEx(OUT_BC,speed_s,angle,0,true,true); } void turnAng(long ang) { long angle; angle=track/diameter*ang; RotateMotorEx(OUT_BC,speed_s,angle,100,true,true); } int searchDirection(long ang) { long angle,tacho_min=0,tacho_corr; int d_min; d_min=500; angle=(track/diameter)*ang; turnAng(ang/2); ResetTachoCount(OUT_BC); OnFwdSync(OUT_BC,speed_s,-100); while(MotorTachoCount(OUT_B)<=angle){ if(SensorUS(S4)<d_min){ d_min=SensorUS(S4); tacho_min=MotorTachoCount(OUT_B); } } OnFwdSyncEx(OUT_BC,speed_s,100,RESET_NONE); until(MotorTachoCount(OUT_B)<=tacho_min||SensorUS(S4)<=d_min); Wait(14); Off(OUT_BC);Wait(500); return d_min; } void tuuzyou() { SetSensorLight(S1); //通常のライントレース long t0; t0=CurrentTick(); while(CurrentTick()-t0<90){ //交差点(黒が一定時間以上)につくまでライントレース if(SENSOR_1>58){ turn_r1; t0=CurrentTick(); }else if(SENSOR_1>53){ turn_r0; t0=CurrentTick(); }else if(SENSOR_1>44){ go_s; t0=CurrentTick(); }else if(SENSOR_1>34){ turn_l0; t0=CurrentTick(); //黒以外はt0をリセット }else{ turn_l1; } } } void massugu() //一定時間の直進 { turn_r1; Wait(150); go_s; Wait(1200); } void massugu2() //一定時間の直進 { turn_l1; Wait(400); go_s; Wait(2000); } void special() //特別なライントレース { SetSensorLight(S1); long t1; t1=CurrentTick() while(CurrentTick()-t1<23500){ //一定時間内は交差点を認識しない if(SENSOR_1>58){ turn_r1; }else if(SENSOR_1>53){ turn_r0; }else if(SENSOR_1>44){ go_s; }else if(SENSOR_1>34){ turn_l0; }else{ turn_l1; } } } void sirotuuzyou() //Dで止まるプログラム { SetSensorLight(S1); long t2; t2=CurrentTick(); while(CurrentTick()-t2<90){ //白を一定時間以上認識したら止まる if(SENSOR_1>58){ turn_r1; }else if(SENSOR_1>53){ turn_r0; t2=CurrentTick(); }else if(SENSOR_1>44){ go_s; t2=CurrentTick(); }else if(SENSOR_1>34){ turn_l0; t2=CurrentTick(); else{ turn_l1; t2=CurrentTick(); //白以外はt2をリセット } } } void gyakutuuzyou() void gyakutuuzyou() //逆走する { SetSensorLight(S1); long t5; t5=CurrentTick(); while(CurrentTick()-t5<90){ if(SENSOR_1>56){ turn_l1; t5=CurrentTick(); }else if(SENSOR_1>51){ turn_l0; t5=CurrentTick(); }else if(SENSOR_1>42){ go_s; t5=CurrentTick(); }else if(SENSOR_1>34){ turn_r0; t5=CurrentTick(); }else{ turn_r1; } } } void gyakuspe() void gyakuspe() //DE間を「逆走」 { SetSensorLight(S1); long t6; t6=CurrentTick(); while(CurrentTick()-t6<6000){ while(CurrentTick()-t6<6000){ //一定時間内は交差点を無視 if(SENSOR_1>58){ turn_l1; }else if(SENSOR_1>53){ turn_l0; }else if(SENSOR_1>44){ go_s; }else if(SENSOR_1>34){ turn_r0; }else{ turn_r1; } } } task main() task main() //ボールを掴んだあと缶の位置を調べるプログラム { go_s; Wait(1000); stoop; RemoteStartProgram(CONN,"CATCH.rxe"); RemoteStartProgram(CONN,"CATCH.rxe"); //通信によりボールを掴む Wait(9000); go_s; Wait(2000); special(); tuuzyou(); massugu(); sirotuuzyou(); SetSensorLowspeed(S4); int d=searchDirection(360); int d=searchDirection(360); //位置を調べる if (d>13.5){ long t3,t4; t3=CurrentTick(); fwdDist(d-13.5); t4=CurrentTick(); stoop; RemoteStartProgram(CONN,"lost.rxe"); Wait(2000); OnRev(OUT_BC,30); Wait(t4-t3); } gyakuspe(); gyakutuuzyou(); go_s; Wait(700); stoop; RemoteStartProgram(CONN,"CATCH.rxe"); Wait(9000); SetSensorLowspeed(S4); int e=searchDirection(100); if (e>12){ fwdDist(e-12.0); RemoteStartProgram(CONN,"lost.rxe"); Wait(2000); stoop; } } *発表会・まとめ [#kc6cdb52] **うまくいったこと [#y35c7d0f] ・ボールを掴む、離す、上げる動作 ・ライントレース ・距離の測定 **なぜうまくいかなかったのか [#l07b5d28] ・すべての位置に置いて練習してなかったので、本番はコードが缶にあたってしまい、倒してしまった。 ・電池の消耗、初期状態(タイヤとキャスターの傾きやツノの開き具合)による誤差 **今後に活かしたい反省点 [#sb76e794] ・あらゆる想定でテストを行う ・誤差が生じたときに修正できるようにプログラミングは簡潔にし、分割するようにする ・初期条件を整える **感想 [#rd087ed7] ひとつのプロジェクトを完遂するために協力しながら作業する経験はなかなかできない経験だったので貴重な授業だった。機械の確実さ・不確実さの両面を知るなかで生物や自然の繊細さを実感した。