目次
今回の課題はロボットで漢字を書くというものだった。漢字は半年の大学生活にまつわる漢字ということで「時」を選んだ。かなり苦労したが本番で一応読めるレベルで書けたので結果はまあまあだったと思う。今回学んだことを次回の課題に活かしたいと思う。
本番で書いた字。本番前の練習ではもっときれいに書けていたので出来としては微妙。
最初は基本の形をそのまま使おうとしたが、ペンをうまく付けられなかったので基本の形から大きく変更しこの形になった。この形の利点はペンを機体の回転軸に下ろすことができることにある。これにより機体を回転させてもペンの位置がずれないため「日」の部分を1度もペンを上げることなく書くことができるのでプログラミングがだいぶ楽になった。
ここからさらに改良できる点としては後輪が挙げられる。この後輪では、床との摩擦が大きく、回転し辛かったり、紙をめくってしまうという問題がある。できれば可動式の後輪にしたかったが、時間が足りず断念した。
工夫した点としては、上で述べたようにペンの先端が車体の回転軸に下りるように位置を調整したことである。そのためにペンの固定箇所を3カ所にし、ペンがずれないようにした。さらに、ペンの上部にペンを押さえる部品を取り付けることにより筆圧を生み出し、さらにペンの初期位置の設定を簡単にしている。
この部分で改良ができる点としては、ギアを咬ませていないことが挙げられる。スピードの調整はモーターのパワーによって行っているため、ペンが重かったら動いていない可能性もある。これからの応用を考えてもギアを入れるべきだったと思う。
まず、プログラムを書く前に問題となったのが、書き順である。ここで気をつけなくてはいけないのはできるだけ方向転換の回数を減らすことにある。いくらペンを回転軸の中心に持ってきたとしても、方向転換の回数が増えればそれだけ誤差も増える。なので、書き順を工夫することで方向転換の回数を減らしている。さらに方向転換の回数を減らすためにバック走行で書く部分もある(右上「土」の横棒、最後の跳ね)。
これが最終的な書き順である。
最初にプログラムを書いたときには方向転換を時間制御で行っていた。しかし、この方法では、誤差が大きくまともに字が書けなかった。そこで教えてもらったのが回転角による制御である。これは、モーターの回転角度を指定するとその角度だけモーターが回ってくれるというものでこれによりバッテリーの残量に関係なく同じ動きをしてくれる。
今回使ったのはRotateMotorExというプログラムである。次にその使用例を示す。
RotateMotorEx(OUT_BC,30,275,100,true,true)//左90度回転のプログラム
括弧の中は、出力するモーター、パワー、回転角、シンクロ率(0で2つのモーターはまったく同じ動き、100または−100で逆の動き)、2つのモーターをシンクロさせるかどうか、指定の回転角だけモーターを回した後止まるかどうかを指定している。
このプログラムにより方向転換をより正確にできるようになり、格段に字をきれいに書けるようになった。
方向転換をRotateMotorExで制御することで時間制御よりはきれいな字が書けるようになったが、それでもかなり不格好な字のままだった。その原因を突き詰めていくと右回転がなぜか正確にできないことが分かった。モーターの回転角をどれだけ調節してもなぜか回転が90度にならないのである。そこで最初の予定では右に曲がるはずだった箇所をバック走行を駆使してできるだけ左回転でできるようにプログラムを変えた。しかし、それでも1カ所だけはどうしても右に曲がる必要があった。なので、そこは仕方なく左に270度回転することにした(それでも右回転より精度がいい)。これにより、今回は右回転を1度も使わないこととなった。
最後にプログラムの全文を載せておく。
#define TYOKUSHIN1 OnFwdSync(OUT_BC,30,0);Wait(200);Off(OUT_BC);Wait(1000);//直進長さ短い #define TYOKUSHIN2(t,s) OnFwdSync(OUT_BC,t,0);Wait(s);Off(OUT_BC);Wait(1000);//直進長さ任意 #define TYOKUSHIN3 OnFwdSync(OUT_BC,30,0);Wait(600);Off(OUT_BC);Wait(1000);//直進長さ長い #define TURN_L RotateMotorEx(OUT_BC,30,275,100,true,true);Wait(1000);//反時計回りに回転 #define UP RotateMotor(OUT_A,30,60);Wait(1000);//ペンを上げる #define DOWN RotateMotor(OUT_A,-30,60);Wait(1000);//ペンを下げる task main() { DOWN; //左側「日」始め TYOKUSHIN2(30,300); TURN_L; TYOKUSHIN2(30,300); TURN_L; TYOKUSHIN3; TURN_L; TYOKUSHIN2(30,300); TURN_L; TYOKUSHIN2(30,350); TURN_L; TYOKUSHIN2(30,300); UP; //左側「日」終わり TYOKUSHIN1; DOWN; TYOKUSHIN3; //右下「寸」横棒 UP; TURN_L; TYOKUSHIN1; TURN_L; DOWN; TYOKUSHIN3; //右上「土」下の横棒 UP; TYOKUSHIN2(-30,300); TURN_L; TURN_L; //270度回転 TURN_L; DOWN; TYOKUSHIN2(30,400); //右上「土」縦棒 UP; TYOKUSHIN2(-30,200); TURN_L; TYOKUSHIN2(30,300); DOWN; TYOKUSHIN2(-30,500); //右上「土」上の横棒(バック走行) UP; TURN_L; TYOKUSHIN2(30,300); DOWN; TYOKUSHIN3; //右下「寸」縦棒 RotateMotorEx(OUT_BC,30,140,100,true,true); Wait(1000); TYOKUSHIN2(-20,300); //右下「寸」跳ね(バック走行) UP; TYOKUSHIN2(-30,300); DOWN; //右下「寸」の点 UP; }