目次 #contents *はじめに [#w580db0e] &ref(2016a/Member/Yukihisa/Mission3/2016a-mission2.png,80%); 今回の課題は、紙コップを運び、重ねるロボットの作成である。 課題2で使ったコースを用いる。上の図で、CとDに紙コップを3つずつ置き、AとBからロボットを動かす。CとDそれぞれから交互に紙コップを運び、交互に重ね、最終的にQの円の中に運ばなければならない。 *ロボット本体の説明 [#s12be98f] 最初はロボット2台でやろうと思っていたが、うまくいかず、1台でやることにした。 &ref(2016a/Member/Yukihisa/Mission3/ロボット1.jpg,20%); &ref(2016a/Member/Yukihisa/Mission3/ロボット2.jpg,20%); &ref(2016a/Member/Yukihisa/Mission3/ロボット3.jpg,20%); 全体図。前方の空間は紙コップを重ねる場所である。 &ref(2016a/Member/Yukihisa/Mission3/ロボット5.jpg,20%); &ref(2016a/Member/Yukihisa/Mission3/ロボット6.jpg,20%); &ref(2016a/Member/Yukihisa/Mission3/ロボット7.jpg,20%); 紙コップを持ち上げ、重ねるところである。 紙コップの幅に合わせて、2本の棒で挟み、モーターで持ち上げてロボットのすぐ前の空間に重ねることができる。 紙コップを持ち上げるタイミングは、光センサーが白と判断したときである。 &ref(2016a/Member/Yukihisa/Mission3/ロボット4.jpg,20%); モーターをリモコンの上につけて、ジグザグの車輪でつなげた。 その下につけられた壁のようなものは、回転するときに重ねた紙コップが倒れないようにするためのものである。 &ref(2016a/Member/Yukihisa/Mission3/ロボット8.jpg,20%); ライントレースするための光センサーは、急カーブでトレースしやすいように、ロボット本体の中心に取り付けた。 黄色いパーツについている丸いものは、バランスをとるためである。 *プログラムの説明 [#d5ee54ee] チームの中で、黒河内君が一番プログラム作成が得意だったので、黒河内君を中心にプログラムを作成した。 ・定義 #define CROSS_TIME 40 #define BALANCE_TIME 40 #define roll_left OnRev(OUT_A); OnFwd(OUT_C); //左回転 #define turn_left OnFwd(OUT_C); Off(OUT_A); //左旋回 #define go OnFwd(OUT_A); OnFwd(OUT_C); //前進 #define turn_right OnFwd(OUT_A); Off(OUT_C); //右旋回 #define roll_right OnFwd(OUT_A); OnRev(OUT_C); //右回転 #define back OnRev(OUT_A); OnRev(OUT_C); Wait(100); Off(OUT_AC); //後退 #define top OnRev(OUT_C); OnFwd(OUT_A); Wait(CROSS_TIME); OnFwd(OUT_AC); Wait(10); //交差点判別後、前進 #define left OnRev(OUT_A); OnFwd(OUT_C); Wait(20); //交差点判別後、左折 #define right OnRev(OUT_C); OnFwd(OUT_A); Wait(80); OnFwd(OUT_AC); Wait(20); //交差点判別後、右折 ・サブルーチン sub line_l(){ int ch=0; //ループ脱出用変数 ClearTimer(0); //交差点判別用のタイマーをリセット ClearTimer(1); //交差点誤判別防止用のタイマーをリセット while(ch==0) //chが0の時はループを続ける { if(SENSOR_2 > 53) //白だったら右回転 { ClearTimer(0); //黒ではないので交差点判別用のタイマーをリセット roll_right; } else if(SENSOR_2 > 52) //弱白だったら右旋回 { ClearTimer(0); //黒ではないので交差点判別用のタイマーをリセット turn_right; } else if(SENSOR_2 > 44) //境界だったら直進 { ClearTimer(0); //黒ではないので交差点判別用のタイマーをリセット go; } else if(SENSOR_2 > 41) //弱黒だったら左旋回 { ClearTimer(0); //黒ではないので交差点判別用のタイマーをリセット turn_left; } else{ //黒だったら左回転 roll_left; } if(FastTimer(0)>CROSS_TIME&&FastTimer(1)>l_time){ //交差点判別 Off(OUT_AC); //車輪を止める PlaySound(SOUND_UP); //音を鳴らす Wait(100); //1秒待つ ch=1; //ループ脱出の為にchを1にする } Wait(1); //0.01秒待つ } } 各地点へ移動するためのサブルーチンである。左の境界部分のライントレースである。 カーブを交差点と誤判してしまうことがあったので、交差点判別用のタイマーと交差点誤判防止用のタイマーを使った。(指定秒数を変数としてl_timeをグローバル変数として定義した) sub balance_l(){ int ch=0; //ループ脱出用変数 ClearTimer(0); //姿勢判別用のタイマーをリセット while(ch==0) //chが0の時はループを続ける { ClearTimer(1); //ライントレース時間判別用のタイマーをリセット while(FastTimer(1)<200&&ch==0) //FastTimer(1)が2秒未満かつchが0の時はループを続ける { if(SENSOR_2 > 53) //白だったら右回転 { ClearTimer(0); //境界ではないので姿勢判別用のタイマーをリセット roll_right; } else if(SENSOR_2 > 52) //弱白だったら右旋回 { ClearTimer(0); //境界ではないので姿勢判別用のタイマーをリセット turn_right; } else if(SENSOR_2 > 44) //境界だったら直進 { go; } else if(SENSOR_2 > 41) //弱黒だったら左旋回 { ClearTimer(0); //境界ではないので姿勢判別用のタイマーをリセット turn_left; } else{ //黒だったら左回転 ClearTimer(0); //境界ではないので姿勢判別用のタイマーをリセット roll_left; } if(FastTimer(0)>BALANCE_TIME) //姿勢判別 { Off(OUT_AC); //車輪を止める PlaySound(SOUND_UP); //音を鳴らす Wait(100); //1秒待つ ch=1; //ループ脱出の為にchを1にする } Wait(1); //0.01秒待つ } if(ch==0) { back; //約2秒分の後退 back; } } } 紙コップを正確にとるために、ライントレースを使って本体の姿勢をまっすぐにするためのサブルーチンである。上記は左境界部分での姿勢制御のプログラムである。 sub balance_r(){ int ch=0; //ループ脱出用変数 ClearTimer(0); //姿勢判別用のタイマーをリセット while(ch==0) //chが0の時はループを続ける { ClearTimer(1); //ライントレース時間判別用のタイマーをリセット while(FastTimer(1)<200&&ch==0) //FastTimer(1)が2秒未満かつchが0の時はループを続ける { if(SENSOR_2 > 53) //白だったら左回転 { ClearTimer(0); //境界ではないので姿勢判別用のタイマーをリセット roll_left; } else if(SENSOR_2 > 52) //弱白だったら左旋回 { ClearTimer(0); //境界ではないので姿勢判別用のタイマーをリセット turn_left; } else if(SENSOR_2 > 44) //境界だったら直進 { go; } else if(SENSOR_2 > 41) //弱黒だったら右旋回 { ClearTimer(0); //境界ではないので姿勢判別用のタイマーをリセット turn_right; } else{ //黒だったら右回転 ClearTimer(0); //境界ではないので姿勢判別用のタイマーをリセット roll_right; } if(FastTimer(0)>BALANCE_TIME) //姿勢判別 { Off(OUT_AC); //車輪を止める PlaySound(SOUND_UP); //音を鳴らす Wait(100); //1秒待つ ch=1; //ループ脱出の為にchを1にする } Wait(1); //0.01秒待つ } if(ch==0) { back; //約2秒分の後退 back; } } } 右境界部分での姿勢制御のプログラムである。 sub cup(){ OnRev(OUT_B); アームを下ろす Wait(50); Off(OUT_B); OnFwd(OUT_AC); while(SENSOR_1<42); 光センサーが紙コップの白を認識するまで前進 Off(OUT_AC); 停止 OnFwd(OUT_B); アームを上げる Wait(50); Off(OUT_B); } 紙コップを持ち上げ、重ねるまでのサブルーチンである。 sub turn(){ OnFwd(OUT_C); //左回転 OnRev(OUT_A); Wait(100); //黒部分から白部分に出るための時間(D地点からC地点への移動時に特に必要) while(SENSOR_2>41); //白部分である場合は回転し続ける Off(OUT_AC); //停止 } C,D地点の紙コップを交互に重ねるために、CD間を往復しなければならなかった。 上記は、そこで使う左回転のサブルーチンである。 sub last(){ OnFwd(OUT_AC); //前進 Wait(50); //約0.5秒待つ Off(OUT_AC); OnRev(OUT_B); //アームを下す Wait(50); //約0.5秒待つ Off(OUT_B); OnFwd(OUT_A); //右回転 OnRev(OUT_C); Wait(100); //約1秒待つ back; //約2秒間後進する(1秒ではアームが紙コップに触れている時があるため) back; } Q地点での紙コップの設置のサブルーチンである。 ・メインプログラム task main () { SetSensor(SENSOR_1, SENSOR_LIGHT); //光センサー1の初期設定(紙コップ認識用) SetSensor(SENSOR_2, SENSOR_LIGHT); //光センサー2の初期設定(ライントレース用) SetSensor(SENSOR_1, SENSOR_LIGHT); //光センサー1の初期設定(紙コップ認識用) SetSensor(SENSOR_2, SENSOR_LIGHT); //光センサー2の初期設定(ライントレース用) OnFwd(OUT_AC); //スタート地点の枠から脱出 Wait(60); OnFwd(OUT_AC); //スタート地点の枠から脱出 Wait(60); //C地点までの移動 line_l(); //左側境界部分をトレース left; //P地点を左折 l_time=400; //次の交差点までの秒数を4秒に設定 line_l(); //左側境界部分をトレース right; //S地点を右折 balance_l(); //左境界部分での姿勢制御 line_l(); //左側境界部分をトレース left; //P地点を左折 l_time=400; //次の交差点までの秒数を4秒に設定 line_l(); //左側境界部分をトレース right; //S地点を右折 balance_l(); //左境界部分での姿勢制御 //紙コップ回収作業 cup(); //1つ目の紙コップ取得 back; //後進 cup(); //1つ目の紙コップ取得 back; //後進 //D地点までの移動 turn(); //左回転 balance_r(); //右境界部分での姿勢制御 turn(); //左回転 balance_r(); //右境界部分での姿勢制御 //紙コップ回収作業 cup(); //2つ目の紙コップ取得 back; //後進 cup(); //2つ目の紙コップ取得 back; //後進 //C地点までの移動 turn(); //左回転 OnFwd(OUT_AC); //前進 Wait(20); balance_r(); //右境界部分での姿勢制御 turn(); //左回転 OnFwd(OUT_AC); //前進 Wait(20); balance_r(); //右境界部分での姿勢制御 //紙コップ回収作業 cup(); //3つ目の紙コップ取得 back; //後進 cup(); //3つ目の紙コップ取得 back; //後進 //D地点までの移動 turn(); //左回転 OnFwd(OUT_AC); //前進 Wait(20); balance_r(); //右境界部分での姿勢制御 turn(); //左回転 OnFwd(OUT_AC); //前進 Wait(20); balance_r(); //右境界部分での姿勢制御 //紙コップ回収作業 cup(); //4つ目の紙コップ取得 back; //約4秒間後進 cup(); //4つ目の紙コップ取得 back; //約4秒間後進 back; back; back; l_time=200; //次の交差点までの秒数を2秒に設定 l_time=200; //次の交差点までの秒数を2秒に設定 //左境界部分へ移動 OnFwd(OUT_C); //左回転 OnRev(OUT_A); Wait(50); OnFwd(OUT_AC); //前進 Wait(30); OnFwd(OUT_C); //左回転 OnRev(OUT_A); Wait(50); OnFwd(OUT_AC); //前進 Wait(30); //Q地点までの移動 line_l(); //左側境界部分をトレース left; //S地点を左折 line_l(); //左側境界部分をトレース left; //P地点を左折 line_l(); //左側境界部分をトレース line_l(); //左側境界部分をトレース left; //S地点を左折 line_l(); //左側境界部分をトレース left; //P地点を左折 line_l(); //左側境界部分をトレース //紙コップの設置 last(); } last(); } *結果 [#f63d7778] 1回目は、紙コップの白を認識する光センサーの不調が原因で、1つも紙コップを重ねることができなかった。基本点0点+技術点5.2点=5.2点だった。 2回目は、作戦通り4つの紙コップを重ねることができた。基本点30点+技術点5.2点=35.2点だった。 *感想 [#g9002fd4] 課題1,2の時はロボット本体を本の通りにある程度作ればよかったが、今回は0から作らなければならなかったので、時間がかかった。しかし、時間をかけた分工夫されたロボットを作ることができた。 プログラム作成では、課題1,2を応用することが多く、今までやってきたことの復習みたいだった。 限られた時間の中で、チームメイトと協力することができ、よかったと思う。