#author("2020-02-04T20:18:55+09:00","Hayashi","Hayashi") #author("2020-02-04T20:26:45+09:00","Hayashi","Hayashi") [[2019b/Member]] #contents 課題2 *課題2 [#t733d938] A地点を出発し、次のいずれかの経路を黒い線にそって動くロボットを作成する (他のメンバーとは別の経路になるようにする)。 #ref(2019b-mission2.png) +A地点から出発 +B +C(直進) +D (一時停止の後、直進) +E, F 通過 +G (一時停止の後、左折) +H (一時停止の後、左折) +I (ボール or キューボイドをつかんでUターン) +H (直進) +J (一時停止) +A地点に入る(ゴール) *ロボットの説明 [#u2c36caa] #ref(001.JPG) このロボットは全体的に,前の方が重くなっており,カーブを苦手としているようです. #ref(002.JPG) 参考に乗っているような,光センサーの場合,上にモーターを付けるのが難しかったため,少し内側にずらしました. #ref(003.JPG) 前の腕は,レゴブロックでくっつけるようにしました.意外と激しい動きにも耐えられたのは意外でした.しかし,全体的にこの車体は前に重心があるため(ボールをつかむ部分や,nxtの本体の部分),CD間でどうしてもガクガク動いてしまい,交差点のところではうまく反応してくれないという欠点があります.実際,そこの難所をクリアーできれば,あとはゴールまで行けました. *プログラムの説明 [#j324c425] **使用したプログラム [#kcb14d75] #define THRESHOLD 55 #define SPEED_H 40 #define SPEED_L 30 #define onRL(speedR,speedL) OnFwd(OUT_B,speedR);OnFwd(OUT_C,speedL); #define go_forward onRL(SPEED_H,SPEED_H); #define turn_left1 onRL(SPEED_L,-SPEED_L); #define turn_left0 onRL(SPEED_L,0); #define turn_right0 onRL(0,SPEED_L); #define turn_right1 onRL(-SPEED_L,SPEED_L); #define STEP 1 #define nMAX 300 #define short_break Off(OUT_BC);Wait(1000); #define CROSS_TIME 1000 #define cross_line onRL(SPEED_L,SPEED_L);Wait(CROSS_TIME);short_break; #define u_turn OnRev(OUT_BC,SPEED_L);Wait(500);onRL(- SPEED_H,SPEED_H);Wait(600);Off(OUT_BC); #define down OnRev(OUT_A,30);Wait(500);Off(OUT_A); sub follow_line() { SetSensorLight(S3); int nOnline=0; int cross=0; while(cross<1){ while(nOnline<nMAX){ if(SENSOR_3<THRESHOLD-15){ turn_left1; nOnline++; }else{ if(SENSOR_3<THRESHOLD-7){ turn_left0; }else if(SENSOR_3<THRESHOLD+7){ go_forward; }else if(SENSOR_3<THRESHOLD+15){ turn_right0; }else{ turn_right1; } nOnline=0; } Wait(STEP); } short_break; cross++; cross_line; nOnline=0; } } sub magaru_line() { SetSensorLight(S3); int nOnline=0; int cross=0; while(cross<2){ while(nOnline<nMAX){ if(SENSOR_3<THRESHOLD-15){ turn_left1; nOnline++; }else{ if(SENSOR_3<THRESHOLD-7){ turn_left0; }else if(SENSOR_3<THRESHOLD+7){ go_forward; }else if(SENSOR_3<THRESHOLD+15){ turn_right0; }else{ turn_right1; } nOnline=0; } Wait(STEP); } short_break; turn_left1;Wait(1000); nOnline=0; cross++; } } sub komawari_line() { SetSensorLight(S3); int nOnline=0; int cross=0; while(cross<1){ while(nOnline<nMAX){ if(SENSOR_3<THRESHOLD-15){ turn_left1; nOnline++; }else{ if(SENSOR_3<THRESHOLD-7){ turn_left0; }else if(SENSOR_3<THRESHOLD+7){ go_forward; }else if(SENSOR_3<THRESHOLD+15){ turn_right0; }else{ turn_right1; } nOnline=0; } Wait(STEP); } turn_left0; cross=0; } } task main() { SetSensorLight(S3); SetSensorLowspeed(S4); int nOnline=0; int cross=0; follow_line(); magaru_line(); while(SensorUS(S4)>9){ if(SENSOR_3<THRESHOLD-15){ turn_left1; nOnline++; }else{ if(SENSOR_3<THRESHOLD-7){ turn_left0; }else if(SENSOR_3<THRESHOLD+7){ go_forward; }else if(SENSOR_3<THRESHOLD+15){ turn_right0; }else{ turn_right1; } nOnline=0; } Wait(STEP); } short_break; down; u_turn; komawari_line(); follow_line(); } **使ったもの [#l5b33675] ***定義したもの; [#e42b4e88] #define THRESHOLD 55 #define SPEED_H 40 #define SPEED_L 30 #define onRL(speedR,speedL) OnFwd(OUT_B,speedR);OnFwd(OUT_C,speedL); #define go_forward onRL(SPEED_H,SPEED_H); #define turn_left1 onRL(SPEED_L,-SPEED_L); #define turn_left0 onRL(SPEED_L,0); #define turn_right0 onRL(0,SPEED_L); #define turn_right1 onRL(-SPEED_L,SPEED_L); #define STEP 1 #define nMAX 300 #define short_break Off(OUT_BC);Wait(1000); #define CROSS_TIME 1000 #define cross_line onRL(SPEED_L,SPEED_L);Wait(CROSS_TIME);short_break; #define u_turn OnRev(OUT_BC,SPEED_L);Wait(500);onRL(- SPEED_H,SPEED_H);Wait(600);Off(OUT_BC); #define down OnRev(OUT_A,30);Wait(500);Off(OUT_A); THRESHOLDで閾値を決めました.SPPED_HとSPEED_Lによって,速さを変えられるようにし,onRL(SPEEDR,SPEEDL)を定義することで,左右のタイヤの速さを細かく調整できるようにしました.途中で大きく黒の方,白の方に行かないように,旋回できるように,turn_right1,turn_left1を定義し,曲がるときには,turn_right0,turn_left0を定義しました.STEPは,一回の判断で動作させる時間,nMAXは交差点の時黒の続く部分をカウントするものです.downはボールのアームを降ろすためのものです. ***関数; [#s38bedf4] 交差点Dを通過するとき,交差点を渡る時に,黒が何回続いたかを,nOnlineによって数えるようにし,これが,nMAXで定義された値を超えると,交差点と認識することで,渡るようにしました sub follow_line() { SetSensorLight(S3); int nOnline=0; int cross=0; while(cross<1){ while(nOnline<nMAX){ if(SENSOR_3<THRESHOLD-15){ turn_left1; nOnline++; }else{ if(SENSOR_3<THRESHOLD-7){ turn_left0; }else if(SENSOR_3<THRESHOLD+7){ go_forward; }else if(SENSOR_3<THRESHOLD+15){ turn_right0; }else{ turn_right1; } nOnline=0; } Wait(STEP); } short_break; cross++; cross_line; nOnline=0; } } 交差点G,Hを左折するとき,上と同じように,nOnlineで数え上げ,交差点と認識した時に,今度は,左に少しずつ,曲がるようにしました. sub magaru_line() { SetSensorLight(S3); int nOnline=0; int cross=0; while(cross<2){ while(nOnline<nMAX){ if(SENSOR_3<THRESHOLD-15){ turn_left1; nOnline++; }else{ if(SENSOR_3<THRESHOLD-7){ turn_left0; }else if(SENSOR_3<THRESHOLD+7){ go_forward; }else if(SENSOR_3<THRESHOLD+15){ turn_right0; }else{ turn_right1; } nOnline=0; } Wait(STEP); } short_break; turn_left1;Wait(1000); nOnline=0; cross++; } } HからJの間の急カーブ HからJの間の急カーブは,曲がる時に,黒が何回も続くせいで,follow_line()を使うと交差点と間違って認識してしまうため,黒い部分が何回も続くときには,小回りが利くように,少し左に曲がるようにしました. sub komawari_line() { SetSensorLight(S3); int nOnline=0; int cross=0; while(cross<1){ while(nOnline<nMAX){ if(SENSOR_3<THRESHOLD-15){ turn_left1; nOnline++; }else{ if(SENSOR_3<THRESHOLD-7){ turn_left0; }else if(SENSOR_3<THRESHOLD+7){ go_forward; }else if(SENSOR_3<THRESHOLD+15){ turn_right0; }else{ turn_right1; } nOnline=0; } Wait(STEP); } turn_left0; cross=0; } } 関数は主に上の3つを定義しました.どの関数にも光センサーを用いました.最初のwhileにtrueをいれてしまうと,光センサーが反応しなくなってしまうので,crossという,交差点にぶつかった回数の上限によって,whileのなかの動作を行い,その回数の上限がきたら終わらせるというふうにしました. 関数は主に上の3つを定義しました.どの関数にも光センサーを用いました.最初のwhileにtrueをいれてしまうと,光センサーが反応しなくなってしまうので,crossという,交差点にぶつかった回数の上限によって,whileの間の動作を行い,その回数の上限がきたら終わらせるというふうにしました. ***task_main()の中身 [#sd556bd2] task main() { SetSensorLight(S3); SetSensorLowspeed(S4); int nOnline=0; int cross=0; follow_line(); magaru_line(); while(SensorUS(S4)>9){ if(SENSOR_3<THRESHOLD-15){ turn_left1; nOnline++; }else{ if(SENSOR_3<THRESHOLD-7){ turn_left0; }else if(SENSOR_3<THRESHOLD+7){ go_forward; }else if(SENSOR_3<THRESHOLD+15){ turn_right0; }else{ turn_right1; } nOnline=0; } Wait(STEP); } short_break; down; u_turn; komawari_line(); follow_line(); } task_main()の中身は,超音波センサーを起動するため,まずセットしました.最初にDを通過するために,定義した,follow_line()を動かし,交差点二つを曲がるために,magaru_line()を動かしました.そして,whileの中で9cm以上に障害物がない間は,HからIの間でライントレースをするようにし,ボールの位置が来たら,アームを降ろして,u_turnを使ってUターンさせ,komawari_line()を用いることで,急カーブを曲がった後に,follow_line()で,Jまでライントレースさせた後,止まらせ,ゴールに入るようにしています. *まとめ [#n2f758ec] 今回は,プログラミングの方でも,車体の方でもてこずりました.whileの中で繰り返すというのが,プログラミングを書いているうちにわけわからなくなってしまい,かなり焦りました.電池がもたなくなると,角の部分で,曲がれないこともありましたが,何とかうまくできてよかったと思います.