目次
A4の紙に今年の大学生活を表す漢字一文字を書くロボットを作製せよ。というものである。僕は今年たくさん失敗をしてしまい苦い思いをしたので「苦」という字をロボットで書こうと思った。
今回のロボットは一番最初に作成した基本のものにペンを上げ下げする部品を取り付けたシンプルな構造になっている。それにより分解するのも簡単になっている。
基本の構造
直角に曲がったりするには車輪は二つのほうがプログラミングしやすいと思ったので、基本のものを崩さずに使用した。曲がるときには二つの車輪を逆方向に回転させる方法をとろうとしたが、やってみて難しく感じたので、片方の車輪を軸にしてコンパスが円を描くようにもう片方の車輪を動かす方法をとった。
float GetAngle(float d) { const float diameter = 5.45; const float pi = 3.1415; float ang = d/(diameter*pi)*360.0; return ang; }
この関数は、距離dから車輪の回転角を計算してくれるものである。これはかなり正確らしいが、実際に動かすと多少のずれが生じるので、実際に動かして検討してみる必要がある。
#define SPEED 30 #define SPEEDm -30
今回は紙が大きく動いたりしないようにスピードを遅めの30に統一する。SPEEDmのmはマイナスの意味である。前進するときはSPEED,後退するときはSPEEDmが入る。
始めは、上の車輪の部分で説明したようにやってみたが回転後に位置がずれてしまったので回転する前後にロボットの位置を調節することによりずれを無くした。GetAngle()内の数字は実際に動かしてみて調節しながら決めた。回転角+右または左という変数名にした。
#define NinetyLeft RotateMotor(OUT_B,SPEED,GetAngle(16));RotateMotor(OUT_BC,-30,GetAngle(9));//左に90度回転 #define NinetyRight RotateMotor(OUT_C,SPEED,Getangle(16));RotateMotor(OUT_BC,-30,GetAngle(9));//右に90度回転
#define TwelveTenLeft RotateMotor(OUT_BC,SPEEDm,GetAngle(3));RotateMotor(OUT_B,SPEED,GetAngle(20));RotateMotor(OUT_BC,SPEEDm,GetAngle(17));//左に120度回転
#define SixtyRight RotateMotor(OUT_BC,SPEED,GetAngle(2));RotateMotor(OUT_C,SPEED,GetAngle(10));RotateMotor(OUT_BC,SPEEDm,GetAngle(7)); //右に60度回転
実際にアームを動かしてモータの回転角を決めた。
#define PenUp RotateMotor(OUT_A,SPEED,60); //ペンを上げる #define PenDown RotateMotor(OUT_A,SPEEDm,60); //ペンを下げる
前に進む命令には進む距離の次にGoを、後ろに下がる命令にはBackを付ける。少々長くなって面倒に感じるが、プログラムを書いたときに一目でどういう動きをするかが分かる。
#define twelveGo RotateMotor(OUT_BC,SPEED,GetAngle(12)); #define tenGo RotateMotor(OUT_BC,SPEED,GetAngle(10)); #define fourfiveGo RotateMotor(OUT_BC,SPEED,GetAngle(4.5)); #define eightGo RotateMotor(OUT_BC,SPEED,GetAngle(8)); #define sixthreeGo RotateMotor(OUT_BC,SPEED,GetAngle(6.3)); #define fourGo RotateMotor(OUT_BC,SPEED,GetAngle(4)); #define twoGo RotateMotor(OUT_BC,SPEED,GetAngle(2)); #define twentyGo RotateMotor(OUT_BC,SPEED,GetAngle(20)); #define fiveGo RotateMotor(OUT_BC,SPEED,GetAngle(5)); #define nineBack RotateMotor(OUT_BC,SPEEDm,GetAngle(9)); #define fiveBack RotateMotor(OUT_BC,SPEEDm,GetAngle(5)); #define fourBack RotateMotor(OUT_BC,SPEEDm,GetAngle(4)); #define twothreeBack RotateMotor(OUT_BC,SPEEDm,GetAngle(2.3)); #define fourfiveBack RotateMotor(OUT_BC,SPEEDm,GetAngle(4.5));
回転する動作をプログラミングしたときは床の上で行っていたので、いざ紙の上で動かしてみると若干ズレが生じた。紙の上と床の上では摩擦が違うからだ。また、紙の上で方向を変える時や紙からはみ出し机の上で方向を変える時があるので、ロボットを動かし様子を見ながらロボットの位置を修正するための前後へ移動するプログラムを差し込んだ。書き順は五画までは正しいもので六画目からは、長方形を左上から書くという風にした。
task main() { PenDown; twelveGo; PenUp; //一画目 nineBack; TwelveTenLeft; twoGo; PenDown; fourBack; PenUp; //ニ画目 twothreeBack; SixtyRight; sixthreeGo; PenDown; fourBack; PenUp; //三画目 twothreeBack; SixtyRight; nineBack; PenDown; tenGo; PenUp; //四画目 fiveBack; twoGo; //位置を修正するために入れた NinetyLeft; // fiveBack; //位置を修正するために入れた twoGo; PenDown; fourfiveBack;// twoGo; //位置を修正するために入れた PenUp; //五画目 NinetyRight; // nineBack; //位置を調節するために入れた PenDown; twelveGo;//ここから書き順の七画目から始めて四角を書く PenUp; fiveGo; //位置を調節するために入れた NinetyRight; fiveBack; //位置を調節するために入れた PenDown; sixthreeGo; PenUp; fiveGo; //位置を調節するために入れた twothreeBack; //位置を調節するために入れた NinetyRight; fiveBack; //位置を調節するために入れた PenDown; twentyGo; PenUp; NinetyRight; twothreeBack; //位置を調節するために入れた PenDown; sixthreeGo; PenUp; }
今回のロボットはfloat GetAngle(float d)という関数を用いたが、タイヤと紙の間の摩擦や電池の状態によってかなりの誤差が出てしまい、頭の中で思い描いていたイメージとだいぶ違う動きをしてしまったので、数値を変えて動かすことを何回もくりかえした。プログラミングは最初に頭の中でロボットの動きを想像してすべてのプログラムを書くのではなく、ロボットの動きを見ながら一画一画丁寧に書いていくほうが、確実でエラーが出た時も対処しやすいと感じた。定義する変数が多くなってしまったので、一つ一つの変数名をわかりやすいものにすることは大事だと思った。ペン先を本隊前部の中央に持ってくるのはやはりプログラミングがしやすかった。タイヤが本体の出っ張りに引っかかって左右の車輪の回転角に違いが生じることがあったが、タイヤを浅めに軸に差し込むことで解決した。このように小さな障害を一つ一つ取り除いていくことが肝心だと実感した。