詳しくはこちら→課題3
当初は2台ロボットを製作予定であったが、赤外線通信の性能が良くなかったので断念し、製作途中であった2台のロボットを強引に融合させたいわば二つの顔を持つロボットとした。筆者の主観で命名するならばType1 :Giraffa、Type2:LifterであるType変更の方法はロボットを反転することで行う。効率性とロマンを求めた最高傑作のロボットである。反転時にドヴォルザークの新世界を流したら面白そうであったが、それでころでなかったので断念。
↑Type1:Lifter
↑Type2:Giraffa
アーム格納
この大きなアームは空き缶を寄せ集めて一列に並べる機構「Giraffa-mandibles」である。最終仕様はアームが2重構造であるが、これは試作機で、最終仕様とはアームの構造が2重か1重かで異なっている。このロボットの名前であるGiraffaはギラファノコギリクワガタ(学名:Prosopocoilus giraffa)から筆者が勝手に命名。
この機構稼働部分には毎回お馴染みのウォームギヤを採用している。ウォームギヤを採用することにより、トルクをあげて空き缶程度の重量であれば、楽々と移動させることが可能だ。当初ロングアームは一重構造であったが、脆いのが原因で問題が発生したため2重構造とした。以下の写真は駆動の様子。
回転数測定器を採用することで、時間差で駆動時間を設定する最大の問題点である電池消耗による誤差の拡大という問題を解決した。
ここは製作するにあたって少々苦労した。モーターの重さで下がってしまうのを防ぐために毎回お馴染み(2回目)のウォームギヤを採用した。
これは機構の中で最も重要なGripである。ここで注目して欲しいのは、クラッチギヤ(白いギヤ)である。モーターの回転を止めてしまうと空き缶が落下する恐れがある、だからと言ってモーターを稼働させ続けて大きく負荷を掛けるのも良くない。そういった状況下において解決可能なアイテムはクラッチギヤだ。クラッチギヤにはトルクが大きくかかると空転する機能がある。これによって両者の問題点を解決した。光センサーによって空き缶を判断可能にしている。ホースは無くてもほとんど変わらないため飾りである。
このロボットの走行ユニットである。走行ユニットのタイヤが幾度も外れたため、余り物のギヤを使用して補強を施した。
補助前輪製作において、取り付け位置であるLiftがとても重いため、外れてしまうことが多くてとても苦労した。外れないようにする方法してはブロックの中に埋め込むことである。これによって脱輪を防いだ。
Giraffaでスタート→アーム駆動→缶寄せ集め→アームを閉じて缶を一直線に整理(ロボコンではここまで)→GiraffaからLifterへ変形するためにアームを収納して後退、そして反転→缶に接近してLifterで缶積み上げ
赤色の丸が缶である。絵のクオリティについては触れないように。
今回のプログラムは複数人で製作するとプログラムエラーの頻発などあり得るため、1人で製作するのが効率がよいと判断し、Kenty氏が製作を担当した。プログラム上の説明でも理解できると思うが、更に 詳しく理解したいのであればKenty氏のレポートを参照することを推奨→Kenty氏のレポート
#define LINE_BLACK 35 //黒線反応時の光センサ(ライン判定用)の値 #define CAN_SHORT 46 //缶に接近したときの 光センサ(缶用)の値 #define TURN_TIME 145 //180°反転までの時間 #define APP_TIME 75 //缶接近までの時間 #define ARM_TIME 200//アー時間直立(アームの駆動時間はこれを基準に使用) #define FOWORD OnFwd(OUT_AC); //直進 #define BACK OnRev(OUT_AC); //後退 #define STOP Off(OUT_AC); //停止 #define TURN_LEFT OnFwd(OUT_C); OnRev(OUT_A); //左旋回 #define TURN_RIGHT OnFwd(OUT_A); OnRev(OUT_C); //右旋回 #define ARM_OPEN OnFwd(OUT_B); //アーム開 #define ARM_CLOSE OnRev(OUT_B); //アーム閉 #define ARM_STOP Off(OUT_B); //アーム停止 #define ROGER 1 //<受信・送信> 【了解】 #define GO_AHEAD 10 //<送信> 【行動開始】 #define MOTION_END 20 //<受信> 【動作完了】
int trans_sign = 0; //<通信> 送信信号 格納用 int can_cnt = 0; //缶 積み上げ本数カウント用
sub Reception() { ClearMessage(); //<通信> 初期化(最後に受信した値 → 0) until(Message() == MOTION_END); //<通信> 『20【動作完了】』を受信するまで待機 SendMessage(ROGER); //<通信> 『1【了解】』を送信 }
sub Transmission() { ClearMessage(); //<通信> 初期化(最後に受信した値 → 0) SendMessage(trans_sign); //<通信> 『"trans_sign"の値』を送信 until(Message() == ROGER); //<通信> 『1【了解】』を受信するまで送信し続ける }
task main() { /*---------- モータパワー・センサ 設定 ----------*/ SetPower(OUT_AC , 3); SetSensor(SENSOR_3 , SENSOR_LIGHT); //黒線 認識用 SetSensor(SENSOR_1 , SENSOR_LIGHT); //缶 認識用 /*---------- アームを全開 ----------*/ ARM_CLOSE; //アーム閉 Wait(ARM_TIME); //アームが真横を向くまで閉じる ARM_STOP; Wait(100); /*---------- 缶 回収 ----------*/ FOWORD; // アーム側を前方向として until(SENSOR_3 < LINE_BLACK); // 2つ目の黒線まで前進 until(SENSOR_3 > LINE_BLACK); // until(SENSOR_3 < LINE_BLACK); // STOP; //停止 Wait(100); ARM_CLOSE; //アーム閉 Wait(ARM_TIME + 50); //アームが平行になるまで閉じる ARM_STOP; Wait(100); BACK; // 缶を揃えるために Wait(50); // 少し下がる STOP; ARM_CLOSE; // アーム閉 Wait(30); // 缶を一列にするためにさらに少し閉じる ARM_STOP; ARM_OPEN; // アームを開き、 Wait(ARM_TIME*2 + 80); // スタート時にあった場所まで戻す ARM_STOP; /*---------- 缶積み上げのための準備 ----------*/ BACK; // 後退して、 until(SENSOR_3 > LINE_BLACK); // 2つ目の黒線まで前進 until(SENSOR_3 < LINE_BLACK); // STOP; //------------------- 発表会ここまで ---------------------------// SetPower(OUT_AC , 7); TURN_LEFT; // 右方向へ Wait(TURN_TIME); // 180°旋回 STOP; SetPower(OUT_AC , 3); BACK; // ハンド側を前方向として until(SENSOR_1 > CAN_SHORT); // 缶の手前まで前進 Wait(20); // (ここから下は、ハンド方向を前方向とする) STOP; /*---------- 缶を積み上げ開始 (3回繰り返し、4段にする) ----------*/ while(pile_up_cnt < 3){ trans_sign = GO_AHEAD; //<通信> 『10【行動開始】』 Transmission(); // ↳送信 /* - - - - - - - - - - - - - - - - -*/ /* ハンド側が缶の持ち上げを実行 */ /* - - - - - - - - - - - - - - - - -*/ Reception(); //<通信> 『20【動作完了】』が送られてくるまで待機 BACK; // 缶一つ分だけ(次の缶の手前まで) until(SENSOR_1 > CAN_SHORT); // 前進する Wait(20); STOP; trans_sign = GO_AHEAD; //<通信> 『10【行動開始】 Transmission(); // ↳送信 /* - - - - - - - - - - - - - - - - - -*/ /* ハンドが缶を置き、初期位置に戻る */ /* - - - - - - - - - - - - - - - - - -*/ Reception(); //<通信> 『20【動作完了】』が送られてくるまで待機 can_cnt++; //缶の本数 +1 } }
#define HAND_TIME 50 //ハンド開閉 時間 #define ELEVATE_UP OnFwd(OUT_C); //<ハンド昇降>上昇 #define ELEVATE_DOWN OnRev(OUT_C); //<ハンド昇降>降下 #define ELEVATE_STOP Off(OUT_C); //<ハンド昇降>停止 #define HAND_OPEN OnRev(OUT_B); //<ハンド開閉>開 #define HAND_CLOSE OnFwd(OUT_B); //<ハンド開閉>閉 #define HAND_STOP Off(OUT_B); //<ハンド開閉>停止 #define ROGER 1 //<受信・送信> 【了解】 #define GO_AHEAD 10 //<受信> 【行動開始】 #define MOTION_END 20 //<送信> 【動作完了】
int trans_sign = 0; //送信用 信号 格納変数 int hand_flag = 0; //<ハンド>開閉 判断用 int elevate_flag = 0; //<ハンド>昇降 判断用 int can_cnt = 0; //積み上げた缶の本数
sub Hand_Elevate() { if(elevate_flag == 0){ //ハンド上昇 ELEVATE_UP; until(SENSOR_1 > 385); ELEVATE_STOP; elevate_flag = 1; //ハンド上昇終了 次:降下を実行 } else if(elevate_flag == 1){ //ハンド降下(缶をのせる) ELEVATE_DOWN; until(SENSOR_1 < 360); ELEVATE_STOP; elevate_flag = 2; //ハンド降下終了 次:下降を実行 } else if(elevate_flag == 2){ //ハンド初期位置(一番下)へ移動 ELEVATE_DOWN; until(SENSOR_1 < 3); ELEVATE_STOP; elevate_flag = 0; //ハンド下降終了 次:上昇を実行 } }
sub Hand_OC() { if(hand_flag == 0){ SetPower(OUT_C , 3); HAND_CLOSE; Wait(100); SetPower(OUT_C , 6); hand_flag = 1; //ハンド閉 次:ハンドを開 } else{ HAND_OPEN; Wait(HAND_TIME); HAND_STOP; hand_flag = 0; //ハンド開 次:ハンドを閉じる } }
sub Reception() { ClearMessage(); //<通信> 初期化(最後に受信した値 → 0) until(Message() == GO_AHEAD); //<通信> 『10【行動開始】』を受信するまで待機 SendMessage(ROGER); //<通信> 『1【了解】』を送信 }
sub Transmission() { ClearMessage(); //<通信> 初期化 (最後に受信した値 → 0) SendMessage(trans_sign); //<通信> 『"trans_sign"の値』を送信 until(Message() == ROGER); //<通信> 『1【了解】』を受信するまで送信し続ける }
task main() { /*---------- モータパワー・センサ 設定 ----------*/ SetSensor(SENSOR_1 , SENSOR_ROTATION); //回転センサ設定 ClearSensor(SENSOR_1); //回転センサ初期化 /*---------- 缶 積み上げ(3回繰り返し、4段にする)----------*/ while(can_cnt < 3){ Reception(); //<通信> 『10【行動開始】』を受信するまで待機 Hand_OC(); //缶をつかむ Hand_Elevate(); //ハンド上昇 trans_sign = MOTION_END; //<通信> 『20【動作完了】』 Transmission(); //送信 /* - - - - - - - - - - - - - - - - - - -*/ /* 駆動側が缶の手前まで移動 */ /* - - - - - - - - - - - - - - - - - - -*/ Reception(); //<通信> 『10【行動開始】』を受信するまで待機 Hand_Elevate(); //ハンド下降 Hand_OC(); //缶を放す Hand_Elevate(); //一番下までハンドを下ろす trans_sign = MOTION_END; //<信号>『20【動作完了】』 Transmission(); // ↳送信 can_cnt++; //缶の本数 +1 } Reception(); }
うまくいかなかったのが残念であるが、ここまでチームで頑張ってきたことがなりより大切であると実感している。旋回してType変更するところが上手くいかなく、缶積み上げは発表に入れることができなかった。反転の部分にとても苦労し、これさえクリアできれば、積み上げることが出来たかもしれない。反転は時間で行うのでなく、センサーで行うべきであったと思う。そうはいっても最終的には5位でそれなりの成果を出すことが出来たのでよかった。これまでのロボット製作を通して、物事は必ずしも上手くスムーズに進行するとは限らないが、それの対する忍耐性の大切さを感じることができた。これまでのロボット製作の忍耐力を忘れずにこれから様々なことを頑張っていきたいと思う。
ロボコンでは缶積み上げは行わなかったので、こちらに缶積み上げの様子は掲載しておいた。機会があればぜひ閲覧して欲しい。 https://youtu.be/tje0arvAjDE