課題については課題3を参照。
この課題では、空き缶を収集するロボットと積み上げるロボットとをくっつけて1台にするか、分けて2台にするかで分かれた。私たちの班は作業効率を考えて、2台に分けることにした。私は缶を積むロボット(主に機体設計)を担当した。
ポートの数の関係上、このロボットは前後運動のみである。また、アーム部分の上げ下げにおいて、アームに直接モーターをつなげると負荷が予想以上にかかったため、歯車を組み合わせ、負荷がかかりづらいようにした。また、缶の検知については、最初スイッチを用いようと思ったが、スイッチが押されずそのまま缶を押してしまったため、超音波センサーを用いることにした。缶を積み上げるロボットの動作の詳細は「プログラムについて」で説明する。
缶を持ち上げるとアーム部分の重さによって機体全体が若干前のめりになってしまったので、缶は水平を保てるように工夫した。
今回の課題では2台の機体によるBluetoothの通信が必須になる。最初私たちの班は信号を送り合って連携をとることを考えたが、うまくいかなかったため、マスター側がスレイブ側にあるプログラムを起動させるようにした。缶を集める収集ロボットがマスター、積み上げるロボットがスレイブである。
このプログラムの動作は
アームを上げる→缶に近づく→アームが缶に干渉しない位置まで下がり、アームを下げ、つかむ部分を開ける→缶をつかむ→アームを上げる
という順番
今回も前回の課題で使った、指定した距離だけ進むように関数を定義した。
#define SPEED 30 #define SPEED_SLOW 20 #define go_forward OnFwd(OUT_B,SPEED)
float GetAngle(float d) // 距離dからタイヤの回転数を計算する関数 { const float diameter = 2.7; // タイヤの半径 const float pai=3.1415; // 円周率 float ang = d/(2*diameter*pai)*360.0; // 角度を計算する return ang; }
sub can() // 缶に近づくサブルーチン { SetSensorLowspeed(S1); // 端子1に超音波センサー go_forward; until(SensorUS(S1) <=7); // 缶から7cmの位置まで前進 Off(OUT_B); PlaySound(SOUND_UP); int angleA = GetAngle(2.5); // 2.5cm進むのに必要な回転角度 RotateMotor(OUT_B,SPEED_SLOW,angleA); // 指定した角度でモータを回転 }
缶を検知してから2.5cm進むのは、缶を確実に機体の中心に持ってくるために、前に設けられたガイドで少しだけ缶を押すためである。
task main()//持ち上げて待機 { OnFwd(OUT_A,50);//アームを持ち上げる Wait(5000); OnFwd(OUT_A,20); // アームを保持 can(); int angleA = GetAngle(10.0); // 10.0cm進むのに必要な回転角度 RotateMotor(OUT_B,-20,angleA); // 指定した角度でモータを回転 RotateMotor(OUT_B,-20,300); // 缶が干渉しない位置まで下がる RotateMotor(OUT_A,-20,400); // アームを下げる Float(OUT_A); RotateMotor(OUT_C,-35,45); // 持つ部分を開ける Wait(600); RotateMotor(OUT_B,20,300); // 缶まで近づく RotateMotor(OUT_C,30,40);//缶をつかむ OnFwd(OUT_C,10); // 缶に力を加え続ける Wait(2400); OnFwd(OUT_A,60); // アームを持ち上げる Wait(6000); int angleB = GetAngle(30.0); // 30.0cm進むのに必要な回転角度 RotateMotor(OUT_B,-20,angleB); // 指定した角度でモータを回転 RotateMotor(OUT_A,-20,400); // アームを下ろす Float(OUT_A); }
このプログラムの詳細はRyomaを参照
このプログラムの動作は
1つ目の缶を持ったままアームを上げる→缶に近づく→アームを少し下げ、缶を積む→アームが缶に干渉しない位置まで下がり、アームを下げ、つかむ部分を開ける→缶をつかむ→アームを上げる
という順番
#define SPEED 30 #define SPEED_SLOW 20 #define go_forward OnFwd(OUT_B,SPEED)
float GetAngle(float d) // 距離dからタイヤの回転数を計算する関数 { const float diameter = 2.7; // タイヤの半径 const float pai=3.1415; // 円周率 float ang = d/(2*diameter*pai)*360.0; // 角度を計算する return ang; }
sub can() // 缶に近づくサブルーチン { SetSensorLowspeed(S1); // 端子1に超音波センサー go_forward; until(SensorUS(S1) <=7); Off(OUT_B); PlaySound(SOUND_UP); int angleA = GetAngle(2.5); // 2.5cm進むのに必要な回転角度 RotateMotor(OUT_B,SPEED_SLOW,angleA); // 指定した角度でモータを回転 }
sub taiki2()//二段持ち上げて待機 { RotateMotor(OUT_A,-20,400); Float(OUT_A); RotateMotor(OUT_C,-30,50); Wait(5000); int angleA = GetAngle(23.5); // 23.5cm進むのに必要な回転角度 RotateMotor(OUT_B,20,angleA); // 指定した角度でモータを回転 RotateMotor(OUT_C,30,55); OnFwd(OUT_C,10); Wait(2000); OnFwd(OUT_A,60); Wait(6000); int angleB = GetAngle(30.0); // 30.0cm進むのに必要な回転角度 RotateMotor(OUT_B,-20,angleB); // 指定した角度でモータを回転 RotateMotor(OUT_A,-20,400); Float(OUT_A); RotateMotor(OUT_C,-30,50); RotateMotor(OUT_B,-20,30); } sub tumu()//缶を積む { OnFwd(OUT_A,50); Wait(5000); OnFwd(OUT_A,20); can(); int angleA = GetAngle(10.6); // 10.6cm進むのに必要な回転角度 RotateMotor(OUT_B,-20,angleA); // 指定した角度でモータを回転 Float(OUT_C); RotateMotor(OUT_A,-10,90); OnFwd(OUT_A,20); Wait(500); RotateMotor(OUT_C,-20,60);//缶を離す int angleB = GetAngle(24.0); // 24.0cm進むのに必要な回転角度 RotateMotor(OUT_B,-20,angleB); // 指定した角度でモータを回転 Off(OUT_A); RotateMotor(OUT_C,20,50); } task main() { tumu(); taiki2(); }
このプログラムの詳細はRyomaを参照
このプログラムの動作は
缶を持ったままアームを上げる→缶に近づく→アームを少し下げ、缶を積む→缶から離れる
という順番
#define SPEED 30 #define SPEED_SLOW 20 #define go_forward OnFwd(OUT_B,SPEED)
float GetAngle(float d) // 距離dからタイヤの回転数を計算する関数 { const float diameter = 2.7; // タイヤの半径 const float pai=3.1415; // 円周率 float ang = d/(2*diameter*pai)*360.0; // 角度を計算する return ang; }
sub can() // 缶に近づくサブルーチン { SetSensorLowspeed(S1); // 端子1に超音波センサー go_forward; until(SensorUS(S1) <=7); Off(OUT_B); PlaySound(SOUND_UP); int angleA = GetAngle(2.5); // 2.5cm進むのに必要な回転角度 RotateMotor(OUT_B,SPEED_SLOW,angleA); // 指定した角度でモータを回転 }
task main() { RotateMotor(OUT_B,20,60); RotateMotor(OUT_C,30,50); OnFwd(OUT_C,10); OnFwd(OUT_A,50); Wait(5000); OnFwd(OUT_A,20); can(); int angleA = GetAngle(11.0); // 11.0cm進むのに必要な回転角度 RotateMotor(OUT_B,-20,angleA); // 指定した角度でモータを回転 Float(OUT_C); RotateMotor(OUT_A,-10,90);//アームを下ろす OnFwd(OUT_A,20); Wait(500); RotateMotor(OUT_C,-20,60);//缶を離す int angleB = GetAngle(24.0); // 24.0cm進むのに必要な回転角度 RotateMotor(OUT_B,-20,angleB); // 指定した角度でモータを回転 Off(OUT_A); RotateMotor(OUT_C,20,50); int angleC = GetAngle(20.0); // 20.0cm進むのに必要な回転角度 RotateMotor(OUT_B,-20,angleC); // 指定した角度でモータを回転 }
空き缶を3段積むことに成功し、基本点18点を獲得した。
基本点の他に技術点でも比較的高得点を獲得することが出来、見事1位を獲得することが出来た。実は、本番まで1回も成功しておらず、本番の2回目で成功した。他の班を見ていると、途中で制作方針を変えたりしている班もあり、最初に作業効率を考えて2台体制で制作したのが良かったのではないかと思った。