課題1(書道ロボット)目次
書道ロボットの製作。 詳細は課題のページを参照。
3つのモーターを
に用いて、ペンで文字を書くロボットを製作した。
車体を前後に動かしながらラックギア(平たいギア)を 使用したアームを左右に動かすことで斜めの線も書くことができる。
移動するアームの左右でバランスをとるため、ペン固定Assyとペン上下モーターAssyを分離し、 アームの左右に配置、モーターの動力をチューブ(紫色)で伝達するようにした。
筆ペンを使用したおかげで味のある文字を書くことができる。
あまり速く動くロボットだと調整が難しい。 そこでこのロボットでは本体の前後の動きもアームの左右の動きもかなり減速している。
前後方向については、(8/24)×(8/40)=1/15 で2段の減速。
アームの移動は、一段(8/24=1/3)減速したものでラックギアを駆動。
最初は、ペン固定部とペン上下モーターを同じ側につけていたのだが、 これだとアームの片方だけ重たくなり、アームが動いた時かなりバランスが悪くなってしまう。 そこで重心を車体の近くに取り安定させるため、ペン上下モータとペン固定部をアームの 反対側に配置した。 その結果、かなり遠い距離に駆動力を伝えなければならないという新たな問題が出てきたが、 これはチューブ(紫色のホース)を使うことで解決できた。
伝達にこのホースと軸の接続は力がかかりすぎると空回りするが、 モータ側の減速比やプーリの径を調節することで適度な力を伝達するクラッチのような役割を 果たすことができ、結果として味のある字になった。 また、ホースを使うことで正確にモータ軸の延長直線上になくても(多少曲がっていても)力を伝達できる簡易ユニバーサールジョイントとしても機能する。
アームを駆動するためのギアだけでアームを上から押えてもアームはグラグラするので、 写真のようにもう一つアーム押え用のギアを配置した。
下記の写真はペン上下モーターAssyである。写真の青いピンだけで脱着できる。
筆の接地角度や固定方法は、いろいろ試した結果、現在のシンプルな形に落ち着いた。ペン接地後さらにモーターを回し続けても、ペンによって車体が持ち上がることなくプーリーが空回りするようにすることもできた。
筆を上げたところ
筆を下げたところ
アームが先端まで来たとき、アームと本体の部品が当たるようになっていて、 それ以上動かないようになっている。 しかしこのようにするとモータが回転しすぎた場合、 ロボットが壊れるかモータに負荷がかかりすぎてしまう。 そこでトルクギア(力がかかり過ぎると空回りする白い特殊なギア)をアーム駆動に使用することで、 この問題を解決した。
特に筆の取り付け部など改良を重ねなければならない箇所は、 なるべく独立させて本体から容易に取り外しできるようにした。
写真のように簡単に分解できるので持ち運びの時も便利である。
ペンの上下やペンの移動・移動量等をマクロ化し、 モーターA/B/Cや具体的なモーター回転時間を気にすることなくプログラムが書けるように工夫した。 そのおかげで、当初の「水木」だけでなく「達筆」を書くプログラムも容易に作成できた。
ギアが浮かずに滑らかに回るように縦方向をビームで補強(反対側も補強してある)。
モータAとBを制御することで、横、縦、左払い、右払いなどの画をマクロとして定義した。 筆の上げ下げはモータCで行い、これは他モータと動きと独立している。 より達筆なロボットにするためには、筆の上げ下げと移動を連動させる必要があるが、これは今後の課題である。
/* 各モータの役割 */ /* 前進/後退 : OUT_A */ /* アーム制御 : OUT_B */ /* ペンの上下 : OUT_C */ #define UNITTIME 13 // 単位時間を定義 /* ペンの上げ下げのためマクロ定義 */ #define pen_down_wait OnFwd(OUT_C); Wait(100) #define pen_up OnRev(OUT_C) #define pen_up_wait OnRev(OUT_C); Wait(100) /* 本体とアームを使って前後左右にペンを動かすためのマクロ定義 */ #define move_left(t) Off(OUT_A); OnRev(OUT_B); Wait(UNITTIME*t); #define move_right(t) Off(OUT_A); OnFwd(OUT_B); Wait(UNITTIME*t); #define move_up(t) OnRev(OUT_A); Off(OUT_B); Wait(UNITTIME*t); #define move_down(t) OnFwd(OUT_A); Off(OUT_B); Wait(UNITTIME*t); #define move_leftup(t) OnRev(OUT_A); OnRev(OUT_B); Wait(UNITTIME*t); // 左上がり #define move_leftdown(t) OnFwd(OUT_A); OnRev(OUT_B); Wait(UNITTIME*t); // 左下がり #define move_rightup(t) OnRev(OUT_A); OnFwd(OUT_B); Wait(UNITTIME*t); // 右上がり #define move_rightdown(t) OnFwd(OUT_A); OnFwd(OUT_B); Wait(UNITTIME*t); // 右下がり #define move_wait(t) Wait(UNITTIME*t); #define move_stop Off(OUT_A); Off(OUT_B); #define move_left_stop(t) Off(OUT_A); OnRev(OUT_B); Wait(UNITTIME*t); move_stop #define move_right_stop(t) Off(OUT_A); OnFwd(OUT_B); Wait(UNITTIME*t); move_stop #define move_up_stop(t) OnRev(OUT_A); Off(OUT_B); Wait(UNITTIME*t); move_stop #define move_down_stop(t) OnFwd(OUT_A); Off(OUT_B); Wait(UNITTIME*t); move_stop #define move_leftup_stop(t) OnRev(OUT_A); OnRev(OUT_B); Wait(UNITTIME*t); move_stop #define move_leftdown_stop(t) OnFwd(OUT_A); OnRev(OUT_B); Wait(UNITTIME*t); move_stop #define move_rightup_stop(t) OnRev(OUT_A); OnFwd(OUT_B); Wait(UNITTIME*t); move_stop #define move_rightdown_stop(t) OnFwd(OUT_A); OnFwd(OUT_B); Wait(UNITTIME*t); move_stop task main() { SetPower(OUT_A,1); SetPower(OUT_B,7); SetPower(OUT_C,2); // 水 - 1画目 pen_down_wait; move_down(10); pen_up; move_wait(1); move_leftup_stop(3); pen_up_wait; // 水 - 2画目 move_leftup(1); move_up_stop(3); pen_down_wait; move_right_stop(3); pen_up; move_wait(1); move_leftdown_stop(3); pen_up_wait; // 水 - 3画目 move_rightup(6); move_right_stop(1); pen_down_wait; pen_up; move_leftdown_stop(3); pen_up_wait; // 水 - 4画目 pen_down_wait; move_rightdown(4); pen_up; move_wait(1); move_right_stop(2); pen_up_wait; // 移動 move_leftdown(8); move_left_stop(2); // 木 - 1画目 pen_down_wait; move_right_stop(8); pen_up; move_left_stop(1); pen_up_wait; // 木 - 2画目 move_leftup(3); move_left_stop(1); pen_down_wait; move_down_stop(9); pen_up_wait; // 木 - 3画目 move_up_stop(6); pen_down_wait; move_leftdown(2); pen_up; move_leftdown_stop(3); pen_up_wait; // 木 - 4画目 move_rightup_stop(5); pen_down_wait; move_rightdown(3); pen_up; move_rightdown(2); move_right_stop(1); pen_up_wait; move_down(5); Off(OUT_ABC); }
2015年6月5日からのこのページのだいたいの訪問者数: 本日1 昨日0 合計&counter([total|today|yesterday]);