- 追加された行はこの色です。
- 削除された行はこの色です。
[[2014b/Member]]
*課題 [#z8832255]
[[mission1:http://yakushi.shinshu-u.ac.jp/robotics/?2014b%2FMission1]]参照。間を書く書道ロボットを作る。
*ロボット組み立て [#k988308e]
初めに作ったロボットは解説書の通り本体の右側からアームが伸びるロボットを組み立てたものだ。(写真なし)しかし、それではペンを横に振り上げ横から振り下ろすアームになってしまい、紙にいい具合にインクが密着しないことが分かったので断念した。そこで一度ロボットを分解し、ペンを上下に振るように作ったロボットがこちらである。
#ref(robo.jpg)
3つ目のモーターを本体の真ん中に取り付け、モーターの回転する部分に直接長いブロックをつけることで簡単にペンを上下に振らせるようにした。ペンは写真の4本青い棒が集中しているところで左右から抑え、ペンをモーターのところまでもってこさせモーター自体で下から支えるのと、上からもゴムで抑える。それによって上下左右からペンを抑えることができた。
*課題攻略に向けて [#va1f2b90]
「間」という漢字に斜線が入っていないことを利用し、初めに縦の線を全て書いた後に横の線を書き足していく方法がプログラムを作る時に簡単になるだろうと思い、そのように課題を進めていくことにした。また、「間」に含まれる「日」の部分を3×3マスの正方形中の1マスにはめ込む、つまり、左上と右上、そして下の段の真ん中のマスに日を入れるイメージでプログラムを組んだ。
「間」という漢字に斜線が入っていないことを利用し、初めに縦の線を全て書いた後に横の線を書き足していく方法がプログラムを作る時に簡単になるだろうと思い、そのように課題を進めていくことにした。縦線、横線共に隣合う線を順に書いていくが、その時にロボットを180度回転させず同じ向きのまま書かせることで少ない移動で隣の線へ移動できる。また、「間」に含まれる「日」の部分を3×3マスの正方形(一辺18cm程度)中の1マスにはめ込む、つまり、左上と右上、そして下の段の真ん中のマスに日を入れるようにプログラムを組めば、縦線を書く時のA間B間をまっすぐの移動で済ますことができるので、このような作戦で課題を進めた。
#ref(tate.jpg)
#ref(yoko.jpg)
*プログラム概要 [#s155748f]
プログラムを組んでいる途中で、先に直角に曲がるにはタイヤをどれくらいの角度回転させればよいか、など部分的な動きのプログラムの数値が分かってから進めるほうが、一連の流れの中で数値を測定していくよりも効率がよいと思い、先にサブルーチンを完成させることから始めた。
**定義・サブルーチン [#lc82e7d7]
#define SPEED 30
sub side90()//3×3マスの1マス分前進する。
{RotateMotorEx(OUT_BC,SPEED,90,0,false,true);}
sub side270()//3×;3マスの3マス分前進する。
{RotateMotorEx(OUT_BC,SPEED,270,0,false,true);}
sub unside90()//3×3マスの1マス分後退する。
{RotateMotorEx(OUT_BC,SPEED,-90,0,false,true);}
sub unside270()//3×3マスの3マス分後退する。
{RotateMotorEx(OUT_BC,SPEED,-270,0,false,true);}
sub side600()
{RotateMotorEx(OUT_BC,SPEED,700,0,false,true);}
sub up()//ペンを持ち上げる。
{RotateMotor(OUT_A,SPEED,-25);}
sub down()//ペンを下ろす。
{RotateMotor(OUT_A,SPEED,25);}
sub adjust()//1マス右にずれる。
sub adjust()//左タイヤを反転させた後右タイヤを反転させ1マス右にずれる。
{RotateMotor(OUT_C,SPEED,-200);
RotateMotor(OUT_B,SPEED,-200);}
sub adjust2()//1マス左にずれる。
sub adjust2()//右タイヤを反転させた後左タイヤを反転させ1マスの半分左にずれる。
{RotateMotor(OUT_B,SPEED,-150);
RotateMotor(OUT_C,SPEED,-170);}
sub adjust3()//1マス左にずれる。位置の調整も含む。
sub adjust3()//右タイヤを反転させた後左タイヤを反転させ1マス左にずれる。
{RotateMotor(OUT_B,SPEED,-200);
RotateMotor(OUT_C,SPEED,-200);}
ここでの位置調整のサブルーチン内の数値が正確でないため後半では思い通りのコースを走らなくなる。
**縦線 [#j16c471f]
task main()
{
ResetTachoCount(OUT_ABC);
RotateMotor(OUT_A,SPEED,-45);
RotateMotor(OUT_A,SPEED,50);
side270();
up();
RotateMotorEx(OUT_BC,SPEED,190,0,false,true);//位置の調整。
adjust();
RotateMotorEx(OUT_BC,SPEED,190,0,false,true);//少し前に出る。これにより次の動作をした時、ペンを振り下ろす位置がちょうど次に書く縦線の始めの位置に合う。
adjust();左タイヤを反転させた後に右タイヤを同じ角度反転させ、隣の縦線に向きを変えずに移動。
down();
unside90();
up();
unside90();
down();
unside90();
up();
adjust();
RotateMotorEx(OUT_BC,SPEED,190,0,false,true);//位置の調整。
adjust();左タイヤを反転させた後に右タイヤを同じ角度反転させ、隣の縦線に向きを変えずに移動。
RotateMotorEx(OUT_BC,SPEED,190,0,false,true);//少し前に出てペンを振り下ろす位置が次に書く縦線の始めの位置に合う。
down();
side90();
up();
side90();
down();
side90();
up();
RotateMotorEx(OUT_BC,SPEED,190,0,false,true);//位置の調整。
adjust();
RotateMotorEx(OUT_BC,SPEED,190,0,false,true);//少し前に出る。これにより次の動作をした時、ペンを振り下ろす位置がちょうど次に書く縦線の始めの位置に合う。
adjust();//左タイヤを反転させた後に右タイヤを同じ角度反転させ、隣の縦線に向きを変えずに移動。
down();
unside270();
up();
ここまでは上手くかける
**横線 [#o62805ce]
side600();//位置の調整。
side600();//横線のSTART位置を少し越えるあたりまで前進。
ResetTachoCount(OUT_ABC);
RotateMotor(OUT_C,SPEED,-360);//90度向きを変える。
RotateMotorEx(OUT_BC,SPEED,-120,0,false,true);//位置の調整。
RotateMotor(OUT_C,SPEED,-360);//左タイヤを反転させて90度向きを変える。
RotateMotorEx(OUT_BC,SPEED,-120,0,false,true);//横線のSTARTの位置にペンが振り下ろされる位置に合わせる。
down();
side90();
up();
side90();
down();
side90();
up();
RotateMotorEx(OUT_BC,SPEED,240,0,false,true);//位置の調整。
adjust2();
RotateMotorEx(OUT_BC,SPEED,240,0,false,true);//少し前に出る。これにより次の動作をした時、ペンを振り下ろす位置がちょうど次に書く横線の始めの位置に合う。
adjust2();//右タイヤを反転させた後左タイヤを反転させ1マスの半分左にずれる。
down();
unside90();
up();
unside90();
down();
unside90();
up();
adjust2();
RotateMotorEx(OUT_BC,SPEED,120,0,false,true);//位置の調整。
adjust2();//右タイヤを反転させた後左タイヤを反転させ1マスの半分左にずれる。
RotateMotorEx(OUT_BC,SPEED,120,0,false,true);//少し前に出る。これによりペンを振り下ろす位置がちょうど次に書く横線の始めの位置に合う。
down();
side90();
up();
side90();
down();
side90();
up();
RotateMotorEx(OUT_BC,SPEED,260,0,false,true);//位置の調整。
adjust3();
RotateMotorEx(OUT_BC,SPEED,260,0,false,true);//少し前に出る。これにより次の動作をした時、ペンを振り下ろす位置がちょうど次に書く横線の始めの位置に合う。
adjust3();/右タイヤを反転させた後左タイヤを反転させ1マス左にずれる。/
unside90();
down();
unside90();
up();
unside90();
adjust2();
RotateMotorEx(OUT_BC,SPEED,180,0,false,true);//位置の調整。
adjust2();//右タイヤを反転させた後左タイヤを反転させ1マスの半分左にずれる。
RotateMotorEx(OUT_BC,SPEED,180,0,false,true);//少し前に出る。ペンを振り下ろす位置がちょうど次に書く横線の始めの位置に合う。
side90();
down();
side90();
up();
side90();
RotateMotorEx(OUT_BC,SPEED,180,0,false,true);//位置の調整。
adjust2();
RotateMotorEx(OUT_BC,SPEED,180,0,false,true);//少し前に出る。これにより次の動作をした時、ペンを振り下ろす位置がちょうど次に書く横線の始めの位置に合う。
adjust2();/右タイヤを反転させた後左タイヤを反転させ1マスの半分左にずれる。
unside90();
down();
unside90();
}
位置調整の動きのはずがタイヤの回転する角度が少し違うので位置調整が多い横線を書く動きでは次第にずれが大きくなっていってしまった。
*感想・反省点 [#o909a219]
まずはプログラムの文字数がやや多くなったところは直す必要がある。上記のメインルーチンを見ると、ひとまとまりで同じ動作をしている部分がいくつかあることや、定義をほとんど使っていないことが分かる。それらをサブルーチンにまとめ、数値を定義化すれば、プログラムはより簡潔になり課題を進める面でも簡単になっただろう。またロボットの位置を変える動作をサブルーチンにして何度も使ったが、その数値が正確でないと、最初は少しのずれで済むが、その動作をする度にずれが大きくなっていくので、妥協が許されない計測が難しかった。
課題についてだが、結果として成功はなかった。数値が正確でないこともそうであるが、ロボット組み立てにも原因はあり、ペンを支える部分が安定していると思っていたのが、ペンを振り下ろす度に少しずつペンがずれ、紙にペンのインク部分をつける動作をさせても、つく時とつかない時ができてしまい、一度も良いものを書くことができなかった。