N14のロボットを作成しました。~ *文字 [#z3bac0b7] 課題1~ ''これまで住んだことのある都道府県名、市町村名、地区名などの中から2文字以上、かつ合計10画以上のものを選び、それをA4の紙を書くロボットを製作せよ''~ に基づき、私の出身の浜田市からとって 「浜田」とした。 *ハード [#kf72856b] +構造の決定 ++前後側、左右側にモーターを1つずつ配置しその動きによって文字を書くロボット ++左右対称にモーターを配置し、その回転軸にペン先がくるように設定し、キャスターを前後に配置し支えるロボット(正方形型になるよう配置)~ &ref(A.jpeg); +原案との変更点~ モーターが普通のものと違い、ギアボックス付きのモーターのように全体の系に対して平行に可動域があるので、系そのものを上から吊り下げる形に変更した。~ &ref(B.jpeg); &ref(C.jpeg);~ 更に、組み立てるとき、使用できるパーツの関係で重心がぶれたので、キャスターを後方に左右対称につけた。~ &ref(B91032F7-142F-4E92-A7B3-9F383D131A03.jpeg);~ +ペンを下ろすクレーン~ 以下の図のような構造にした。~ 図~ &ref(DF4771B1-4392-408B-9C12-478901373EED.jpeg);~ 実際に搭載した写真~ &ref(2D4229F0-8F58-4ECB-8C3A-B5FD27B9D24A.jpeg);~ 工夫した点としては~ -ギアを入れたことで少しモーターの元々の可動域とずれたように動かせるようにした。~ -ギアを含め両側から挟んだことで安定性を向上させた点~ が挙げられる。~ その他ハード全体としての工夫点~ 正確な動きにするため低速での運転を想定して、極端に大きさの違うギアを2つかまして、低速でもパワーが落ちないようにした。またこれにより、ペン先の位置、すなわちクレーンの位置が定めやすくなった。~ &ref(ギア.jpeg); *プログラム [#s8f0bb34] -方針~ 1文字あたり6×6の枠を用意し、一つの正方形の一辺をA、対角線をBとした。~ &ref(マス.jpeg);~ これを使って座標もどきの設定をしていく。~ &ref(座標もどき.jpeg);~ 全体像はこのようになる。手数は非常に多い。因みにこの図の番号は動作の手順で、必ず各番号の手順は「→回転(必要な場合のみ)→ペンを置く又は離す動作(必要な場合のみ)→移動(前進又は後退)→」の順で構成されるようにした。~ この図から理解できるように、全ての動作は全てペンの上げ下げと、直進又は後退、ペン先を回転中心とした回転(それも45度か90度のみ)でできるよう仕組んだ。~ -マクロ定義~ ++直進、後退、右回転、左回転 #define Turn_right(r) repeat(r){OnFwd(OUT_C,50);\ OnRev(OUT_B,50);Wait(1);Off(OUT_BC);} #define Turn_left(l) repeat(l){OnFwd(OUT_B,50);\ OnRev(OUT_C,50);Wait(1);Off(OUT_BC);} #define GO(g) repeat(g){OnFwd(OUT_B,50);\ OnFwd(OUT_C,48);Wait(1);Off(OUT_BC);} #define BACK(b) repeat(b){OnRev(OUT_B,50);\ OnRev(OUT_C,48);Wait(1);Off(OUT_BC);} 順に右回転、左回転、直進、後退のマクロ定義である。~ 工夫した点は3つ。~ 工夫点A.それぞれのマクロでは、関数を用いて、適当な時間で統一された動きができるようにした。~ 工夫点B.モーターにガタがきているのか、はたまた不良品なのか、いろんな考察はできるが、ともかく直進、後退において、距離が長ければ長いほどブレが目立ち、カーブした。そこで微調整をした。モーターBとCのパワー値が一致していないのはこのためである。センサーを使っていないのでこれ以外に解決策がなかった。~ 工夫点C.当初は~ #define Turn_right(r) OnFwd(OUT_C,50);\ OnRev(OUT_B,50);Wait(r); #define Turn_left(l) OnFwd(OUT_B,50);\ OnRev(OUT_C,50);Wait(l) #define GO(g) OnFwd(OUT_B,50);\ OnFwd(OUT_C,48);Wait(g); #define BACK(b) OnRev(OUT_B,50);\ OnRev(OUT_C,48);Wait(b); のように、マクロの変数はWait()の中身となるようにしていた。~ しかし、可能な限り同じ条件で実験し続けても、確実に同じ距離を走ることができない。 そこで上の完成形にように、動作→1/100待つ→停止の流れを変数の回数繰り返すという形にした。~ これはえ絶え間なくほんの一瞬ブレーキをかけることで正確さが増すのではないかという推察に基づく。~ 1/100秒という微々たる時間では変化がないと思って試しにやってみただけだが、ほかの工夫の効果もあって、修正以前と比べると実際に動きの正確さが向上した。~ ++A&Bに関して~ A、Bに関する距離を直進、後退する時に使う時間指定用のマクロである。つまり、上で定義した変数付きマクロの中身となる値である。 #define A_1 550 #define B_1 700 #define A_2 1260 #define B_2 1720 #define A_3 1880 #define A_4 2460 #define B_5 3920 当初はプログラム上では、Aのn倍移動するときの時間設定をA_nと定義し、Bも同様に定義したが、トライアンドエラーをしているうちにrepeat記号を用いてA_1またはB_1の時間分の動作を繰り返した方が正確さが増すことに気づいたため、A_1とB_1以外は使わなくなった。(一応名残として取っておいた、というのも、制作過程において、もともとのA_3などがtask mainの中に残っていても、それはそれで修正前との違いを観察できるためであり、プログラム上のエラーは出ないからでもある。)~ ++DEG45&DEG90に関して~ 同様に、45度、90度回転にかかる時間も定義した。~ #define DEG_45 1900 #define DEG_90 3350 しかし、A、Bの時同様に、45度の時間分の動作を整数倍して使うようになったので、必要なのはDEG_45のみとなった。以下補足も上に同じである。~ ++P_ONとP_OFFに関して~ 順にペンを置く動作、ペンを離す動作のマクロを定義した。~ #define P_ON;OnFwd(OUT_A,40);\ Wait(500);Off(OUT_A); #define P_OFF OnRev(OUT_A,40);\ Wait(500);Off(OUT_A); これに関しては、ひたすらトライアンドエラーを繰り返し、モーターのパワー、スピードを調節し、着実に動作するように定義した。それ以外は特に工夫点はない。~ -task main~ 定期的に付いている//番号の数字は、上で示した座標もどきの手順の番号と一致している。~ ++浜の字を書く~ 1~5:氵を書く~ &ref(1to5.jpeg); task main() { Turn_left(DEG_45); P_ON;BACK(B_1);//1 P_OFF;Turn_right(DEG_45); BACK(A_2);//2 Turn_left(DEG_45); P_ON; GO(B_1);//3 P_OFF; Turn_right(DEG_45); BACK(A_4);//4 Turn_right(DEG_45); P_ON; GO(B_1);//5 6:ペンを離し丘の右上まで移動~ &ref(6.jpeg); P_OFF; repeat(5){GO(B_1)};//6。ただし7はプログラム上の設計ミスのため消滅 8~16:丘を書く~ &ref(8to16.jpeg); P_ON; BACK(B_1);//8 Turn_right(DEG_45); repeat(2){BACK(A_1)};//9 repeat(2){Turn_left(DEG_45)}; repeat(3){BACK(A_1)};//10 P_OFF; repeat(2){Turn_right(DEG_45)}; BACK(A_1);//11 P_ON; repeat(4){GO(A_1)};//12 P_OFF; BACK(A_1);//13 repeat(2){Turn_left(DEG_45)}; P_ON; repeat(2){GO(A_1)};//14 P_OFF; repeat(2){Turn_left(DEG_45)}; BACK(A_1);//15 P_ON; repeat(3){GO(A_1)};//16 17~22:ハの左上まで移動しハを書く(ハまでの移動は17のみ)~ &ref(17to22.jpeg); P_OFF; repeat(2){Turn_right(DEG_45)}; repeat(3){BACK(A_1)};//17。ただし18はプログラム上の設計ミスのため消滅 P_ON; Turn_right(DEG_45); BACK(B_1);//19 P_OFF; Turn_left(DEG_45); repeat(2){Turn_left(DEG_45)}; repeat(4){BACK(A_1)};//20 Turn_right(DEG_45); P_ON; GO(B_1);//21 P_OFF; BACK(B_1);//22 23~24:浜の右下から田の右上へ移動~ &ref(23to24.jpeg); Turn_right(DEG_45); repeat(2){BACK(A_1);};//23 repeat(2){Turn_left(DEG_45)};GO(A_1);//24 ++田を書く~ 25~28:外枠の正方形を書く~ &ref(25to28.jpeg); P_ON; repeat(4){GO(A_1)};//25 repeat(3){ repeat(2){ Turn_left(DEG_45)}; repeat(4){GO(A_1) } };//26から28 これまではただ番号に従ってやってきたが、26~28は同じ動作の繰り返しが3回続いたので、repeat を使って繰り返しした。~ 29~32:田の右上からの移動(29)と十の字を書く(30~33)~ &ref(29to32.jpeg); P_OFF; repeat(2){BACK(A_1)};//29 repeat(2){Turn_left(DEG_45)}; P_ON; repeat(4){GO(A_1)};//30 P_OFF; Turn_right(DEG_45); repeat(2){BACK(B_1)};//31 Turn_right(DEG_45); P_ON; repeat(4){GO(A_1)};//32 P_OFF;//最後にペンを上げて完成 } 完成した文字がこれである。~ &ref(complete.jpeg) &ref(complete.jpeg); *反省点 [#cf89d495] 試行錯誤を繰り返すことで、そこそこ綺麗な文字を書くことができた。~ しかしながら、色々な工夫を凝らしたつもりだが、まだ人間である私が書いた方が綺麗だ。これでは人間の代わりにはなり得ない。この設計ではここまでの正確さが一定の限界点だと感じた。言い換えれば、設計が安直すぎたというのが第1の反省点である。~ 第2の反省点は、マクロに頼っても簡略化など全くできていないということである。ロボットが動くまでも、完成したプログラムに説明を入れるのも、全体に煩雑ゆえに(文章的にも作業時間的にも)長すぎる事態となった。工夫をもっと凝らしていれば、頭をもっと捻っていれば、もっと簡略化できたのではないだろうか。~ 第3の反省点としては、ミスで番号がずれたことである。番号がずれるのは整合性を欠くという意味であまりよろしくない。このロボティックス入門ゼミ以外にも人間としての作業の正確さを問われる場面があるので、以後気をつけたい。 *MOVIE[#a10a29b7] [[youtubeより実演動画・浜田を書くロボット:https://youtu.be/3FE_bo1eVRA]]~ (URLからのみアクセスできる限定公開)