目次
書道をする(今回は「長」、「松」という文字を書く)ロボットの作成。
文字の微妙なカーブ具合を表現することによって、出来るだけ人が書いたような字に近づける。
ペンを上げ下げし、ロボット本体が動くことで文字を書くロボットを作成した。
ロボットは、本体をのせる土台、ペンを上げ下げする機構の主に二つの部分から構成した。
タイヤを用いた土台を作成した。
タイヤを用いた理由は、キャタピラなどと比べ地面との摩擦が少なくなるため、より滑らかな動きが出来るからである。
ペンを持たせる機構として、大きな車輪を四つ用いてその間にペンを挟む構造にした。 ペンの上げ下げは、ペンを挟んだ車輪を回転させることで行う。
void gos(int t) //直進 { OnFwd(OUT_A+OUT_C); Wait(t); Off(OUT_A+OUT_C); } void right(int t)//右旋回 { OnFwd(OUT_C); OnRev(OUT_A); Wait(t); Off(OUT_A+OUT_C); } void left(int t)//左旋回 { OnRev(OUT_C); OnFwd(OUT_A); Wait(t); Off(OUT_A+OUT_C); } void goba(int t)//後進 { OnRev(OUT_A+OUT_C); Wait(t); Off(OUT_A+OUT_C); } void fr(int t)//直進してから元の位置までもどる { OnFwd(OUT_A+OUT_C);Wait(t); OnRev(OUT_A+OUT_C);Wait(t); Off(OUT_A+OUT_C); } void giaf(void)//ギアをさげる { Float(OUT_B); OnFwd(OUT_B); Wait(10); Off(OUT_B); } void giar(void)//ギアをあげる { Float(OUT_B); OnRev(OUT_B); Wait(10); Off(OUT_B); } task main(){ //1画目 giaf(); goba(50); gos(50); giar(); left(73); //2画目 giaf(); gos(100); giar(); goba(66); left(73); //3画目 giaf(); fr(50); giar(); right(73); gos(33); left(73); //4画目 giaf(); fr(50); giar(); left(73); gos(33); left(73); gos(50); //5画目 giaf(); goba(150); giar(); gos(130); left(73); //6画目 giaf(); gos(80); giar(); left(123); //はねの部分 giaf(); fr(40); giar(); right(123); goba(80); left(73); gos(10); right(42); gos(40); left(75); //7画目 giaf(); fr(30); giar(); right(75); goba(40); //8画目 giaf(); gos(170); giar(); }
#define A 88 #define B 10 void gos(int t) //直進 { OnFwd(OUT_A+OUT_C); Wait(t); Off(OUT_A+OUT_C); } void right(int t)//右旋回 { OnFwd(OUT_C); OnRev(OUT_A); Wait(t); Off(OUT_A+OUT_C); } void left(int t)//左旋回 { OnRev(OUT_C); OnFwd(OUT_A); Wait(t); Off(OUT_A+OUT_C); } void goba(int t)//後進 { OnRev(OUT_A+OUT_C); Wait(t); Off(OUT_A+OUT_C); } void fr(int t)//直進してから後進 { OnFwd(OUT_A+OUT_C);Wait(t); OnRev(OUT_A+OUT_C);Wait(t); Off(OUT_A+OUT_C); } void giaf(void)//ギアをさげる { Float(OUT_B); OnFwd(OUT_B); Wait(10); Off(OUT_B); } void giar(void)//ギアをあげる { Float(OUT_B); OnRev(OUT_B); Wait(10); Off(OUT_B); } task main(){ //1画目 giaf(); goba(50); gos(50); giar(); left(A); //2画目 giaf(); gos(100); giar(); goba(66); left(A); gos(B); //3画目 giaf(); fr(50); giar(); goba(B); right(A); gos(33); goba(10); left(A); gos(B); //4画目 giaf(); fr(50); giar(); goba(B); right(A); gos(32); goba(B); left(A); goba(50); //5画目 giaf(); gos(150); giar(); goba(130); right(A); //6画目 gos(B); giaf(); gos(80); giar(); goba(20); left(123); //長のはねの部分 giaf(); fr(40); giar(); right(123); gos(B); goba(80); left(A); gos(10); right(42); gos(40); left(75); //7画目 giaf(); fr(30); giar(); right(A); goba(30); //8画目 giaf(); gos(170); giar(); }
#define TURN_TIME 6 //π/24回転 #define TURN_90 74 //π/2回転 sub turn_right(){ //右に90度回転 OnRev(OUT_A); OnFwd(OUT_C); Wait(TURN_90); Off(OUT_A+OUT_C); } sub turn_left(){ //左に90度回転 OnFwd(OUT_A); OnRev(OUT_C); Wait(TURN_90); Off(OUT_A+OUT_C); } sub turn_right45(){ //右に45度回転 OnRev(OUT_A); OnFwd(OUT_C); Wait(TURN_90/2); Off(OUT_A+OUT_C); } void turn_right_free(int theta){ //右にπ/24×与えられた値(theta)回転 OnRev(OUT_A); OnFwd(OUT_C); Wait(TURN_TIME*theta); Off(OUT_A+OUT_C); } sub turn_left45(){ //左に45度回転 OnFwd(OUT_A); OnRev(OUT_C); Wait(TURN_90/2); Off(OUT_A+OUT_C); } void turn_left_free(int theta){ //左にπ/24×与えられた値(theta)回転 OnFwd(OUT_A); OnRev(OUT_C); Wait(TURN_TIME*theta); Off(OUT_A+OUT_C); } sub up(){ //ペンを上げる OnRev(OUT_B); Wait(20); Off(OUT_B); } sub down(){ //ペンを下げる OnFwd(OUT_B); Wait(50); Off(OUT_B); } void Forward(int time){ //前進!! OnFwd(OUT_A+OUT_C); Wait(time); } void Reverse(int time){ //後退!! OnRev(OUT_A+OUT_C); Wait(time); } /**** 本文 ***/ task main(){ int i; SetPower(OUT_A+OUT_C,7); //ロボットを動かすためのモーター二つの強さをそろえる。 SetPower(OUT_B,3); //ペンを上げ下げするモーターの強さを決める。 「木」辺を書く /** 一画目 **/ down(); Forward(45); up(); turn_right_free(3); //二画目の位置へ移動 Reverse(55); turn_right_free(10); //書く方向へ向きを変える /** 二画目 **/ down(); Forward(140); up(); turn_left_free(1); /** マシンの位置を微調整しつつ三角目を書き始める位置へ移動 **/ Reverse(118); //Off(OUT_A+OUT_C); turn_right_free(6); //書く方向へ向きを変える /** 三画目 **/ down(); SetPower(OUT_A,1); //右カーブを描くため右側のモーターの出力を下げる Forward(90); up(); turn_right_free(4); //四画目を書く位置へ移動 Reverse(108); turn_left_free(14); SetPower(OUT_A,7); down(); /** 四画目 **/ Forward(25); up(); 「木」辺終了 Reverse(40); //次の線を書く場所へ移動 turn_left_free(22); Forward(80); turn_left_free(2); down(); /** 五画目 **/ SetPower(OUT_C,2); //左カーブを描くため左の車輪の出力を弱める。 Reverse(95); Off(OUT_A+OUT_C); SetPower(OUT_C,7); up(); Forward(85); turn_left_free(5); down(); /** 六画目 **/ SetPower(OUT_A,1); //右カーブを描くため右の車輪の出力を弱める。 Reverse(105); SetPower(OUT_A,7); up(); turn_left_free(8); /** 七画目を書く位置へ移動 **/ Off(OUT_A+OUT_C); Forward(47); turn_left_free(11); down(); /** 七画目 **/ Forward(60); turn_right_free(9); Reverse(38); up(); turn_right_free(7); /** 八画目を書く位置に移動 **/ Forward(42); Off(OUT_A+OUT_C); turn_right_free(3); down(); /** 八画目 **/ Reverse(30); Float(OUT_A+OUT_C); up(); }
全体図
正面 横
後 上
修正前のロボットでは、動作時に倒れないようにする装置と床との摩擦が大きく動作の邪魔になっていたので修正した。
修正ポイント
マシンの回転する角度を微調整するために何度かプログラムを書きなおしたが 引数を間違って入力してしまったりしたためバグをつくってしまった。
したがってプログラムを作った後の調整をしやすいようにマクロを効果的に使った ほうがいいことを学んだ。
マクロを使うことのメリットは数値の管理を一箇所に集約することができ、また、マクロ名は自由に決められるため設定する定数に関連したマクロ名を設定しておくことでtask内のプログラムを直接書き換える時よりもバグが減りマシンの動作のイメージがよりしやすい状態でプログラムが行えることだといえる。
解決策として倒れなくなるような装備を追加した。
問題点
この構造では前の車輪が向く方向が揺らいでしまう(回転する方向に自由度を持たせた代償)。 ロボットは直進するときには前の車輪の向きの方向に依存するので、この問題のため、直進時にぶれが生じる。
問題点
土台を大きく修正する必要がある。
今回製作したロボットでは、装着することの出来るペンの太さに制限があった。
ペンを持たせる機構を可変な機構に改良することによって、太さの制限を取り払うことが出来ると考えられる。
よろしければコメントお願いします。