目次
今回制作したロボットは、車体は前後運動のみでペン部分が上下左右に動くタイプのロボットです。ペンを付けた車体が動くことで文字を書くロボットも考えましたが、正確な動作が難しいこととプログラムが複雑になることからこのタイプのロボットを制作しようと考えました。しかし、このタイプのロボットは制作するのが難しく、完成するまでには数多くの苦労がありました。
ロボットの全景
本体は最初に制作したので、今後の制作に支障をきたさないよう、必要最小限のパーツで制作しました。その結果、非常にシンプルなものになりました。車体の前から後ろまでを一本のパーツで作ったので、十分な丈夫さも 確保することができました。
上から見た本体
最も苦労した部分。最初はラックとギアを使って左右の動きを作ろうとしましたが、それでは左右の作動範囲が狭く、大きな文字が書けないためタイヤによる摩擦で長いアームを動かすことにしました。キャタピラに使う白いパーツがアームの幅にちょうど合ったので、それを使って下から支え、上からタイヤで押さえつけるという形にしました。
上から見たところ
横から見たところ
はじめはペンを支える部分とモーターを車体左側にまとめて取り付けましたが、アームを左側にのばしたときに車体が左に倒れてしまうため、モーターを右側に移しました。動力の伝達が大変になりましたが、ロボットが倒れる問題は解決することができました。動力はシャフトを3本つなげることで伝達しています。また、ペンを上下させる部分はギヤの使用が困難だったためベルトを使用しましたが、これが逆に適度な筆圧を生むことになり役立ちました。ペンは輪ゴムを使って取り付けましたが、取り付け部の上部にストッパーを付けることでずれないようにしています。
外側から見たところ
車体側から見たところ。上部にストッパーがある
今回は二人の名字から「中」、「戸」という字を書くプログラムを制作しました。
#define YS 100 //短い縦線を書く時間 #define YL 300 //長い縦線を書く時間 #define X 200 //横線を書く時間 #define P 30 //ペンを上下させる時間 sub ys_fwd() //「中」の短い縦線上→下 { OnFwd(OUT_C); Wait(YS); Off(OUT_C); } sub ys_rev() //「中」の短い縦線下→上 { OnRev(OUT_C); Wait(YS); Off(OUT_C); } sub yl_run() //「中」の長い縦線上→下 { OnFwd(OUT_C); Wait(YL); Off(OUT_C); } sub x_fwd() //「中」の横線左→右 { OnFwd(OUT_B); Wait(X); Off(OUT_B); } sub x_rev() //「中」の横線右→左 { OnRev(OUT_B); Wait(X); Off(OUT_B); } sub xy_run() // { OnRev(OUT_C+OUT_B); Wait(YS); Off(OUT_C+OUT_B); } sub pup() //ペンを上げるプログラム { OnFwd(OUT_A); Wait(P); Off(OUT_A); } sub pdw() //ペンを下げるプログラム { OnRev(OUT_A); Wait(P); Off(OUT_A); } task main() //メインのプログラム { pdw(); //ペンを下げる ys_fwd(); //1画目 pup(); //ペンを上げる ys_rev(); //2画目の開始点へ pdw(); //ペンを下げる x_fwd(); //2画目 ys_fwd(); pup(); //ペンを上げる x_rev(); //3画目の開始点へ pdw(); //ペンを下げる x_fwd(); //3画目 pup(); //ペンを上げる xy_run(); //4画目の開始点へ ys_rev(); pdw(); //ペンを下げる yl_run(); //4画目 pup(); //ペンを上げる OnRev(OUT_B); //アームを元の位置に戻す Wait(YS); Off(OUT_B); }
「中」の字を1本ずつの線に分解すると共通部分が多いため,それらをx軸,y軸と長短,方向で分け(例えばプログラム中のys_runはy軸の短い書き順方向の線)それぞれをサブルーチンで表しておくことでメインのプログラムを簡単にすることができました.文字の性質上,ロボットの動きはほぼ直線的ですが,1部4画目の開始点に移動する際,2つのモーターを同時に動かすことで斜めに移動するようにし,時間を短縮しています.
void go_back(int t){OnRev(OUT_C); Wait(t);Off(OUT_C)} //ペンを進ませる(下に進む) void go_straight(int t){ OnFwd (OUT_C); Wait(t);Off(OUT_C);} //ペンを戻す void go_right(int t){OnFwd(OUT_B); Wait(t);Off(OUT_B);} //ペンを右に動かす void go_left(int t){OnRev(OUT_B);Wait(t);Off(OUT_B);} //ペンを左に動かす void go_up(int t){OnRev(OUT_A);Wait(t);Off(OUT_A);} //ペンを上げる void go_down(int t){OnFwd(OUT_A);Wait(t);Off(OUT_A);} //ペンを下げる task main() {go_down(40); //ペンを下げる go_right(80); //一画目 go_up(40); //ペンを二画目の始めまで動かす go_straight(30); go_left(100); go_down(40); go_right(120); //二画目 go_straight(50); go_up(40); //ペンを三画目の始めまで動かす go_left(120); go_down(40); go_right(120); //三画目 go_up(40); //ペンを四画目の始めまで動かす go_left(120); go_back(50); go_down(40); repeat(10) //四画目(右曲がりの曲線) {go_straight(5); go_right(4);} repeat(5) //左曲がりの曲線 {go_straight(5); go_left(4);} repeat(5) //さらに左曲がりの曲線 {go_straight(4); go_left(3);} repeat(5) //もっと左曲がりの曲線 {go_straight(3); go_left(2);} go_up(40); //ペンを上げる Float(OUT_A);} //停止
①曲線を書くために: 結局、このロボットは筆の3次元での動きを、3つの方向の直線運動に分解している。 そして、それぞれを3つのモーターに分担させている。各モーターは100分の1秒単位でしか動けないため、細いペンでは原理的には直線しか書けず、滑らか曲線を書けない。曲線(に見えるような図形)を書くために以下の2つの方法を考え、2番目をとった。
(a)角度を少しずつ変えて、細かい直線をつなげていく 左右運動と上下運動(平面内)を司るモーターを同時に動かせば、斜めの直線となる。これの角度を垂直から水平に近いものに徐々に変えていけば、曲線に見えるはずだ。角度が変化する所が目立たないように、できるだけ細かく変化させるとよい。
(b)細かい折れ線をつなげていく 非常に細かい折れ線は離れた所からは、折れ線に見えない。(a)と同じように、90°に曲がる折れ線の、横に進む長さを少しずつ大きくすることで、「はらい」に見えるようにした。
②関数の使用: 上に述べた3つの方向×2(正と逆)の関数を作った。画単位の関数ではなく、ここまで動きを分解した関数を作ったのは、「戸」という漢字は同じような動きをする画がないし、この6つの動きを組み合わせることで基本的に他の全ての文字も書くことができるからだ。
全体的に必要最小限のパーツで制作したため、壊れやすく持ち運びが大変になってしまいました。分解して運ぶにも、別の部分も壊れてしまい、さらなる補強が必要だと思います。また、ペン上下部分に何段もベルトを使用したため、動作が不正確になってしまいました。
よろしければコメントをどうぞ
これは
+箇条書きの例 +これも +ここも
と編集することで実現できます。 by まいける