[[2018a/Member]] 車型の文字を書くロボットを製作した。~ XY方式での製作も考えたが、無限軌道がなかったため断念した。~ 下にはロボットの写真を載せる~ &ref(2018a/Member/Kkun/Mission1/IMG_20180601_165213432.jpg,50%,習字ロボ); *目次 [#d8823147] #contents *遭遇した問題 [#v38d9e90] -最初タイヤの回る角度を調整できる関数を使用していたが、バッテリーの消費で角度指定すら正確性を欠く。 -角度を指定して回す関数は、2つ同時に実行することができなかった -最初、タイヤを前方につけていたが、この場合タイヤのガタが動きに支障をきたす -NXTは他のロボットに比べて精度が悪いので、誤差を如何に小さくするかが問題となった *工夫したポイント [#p5169e0a] -方向転換を多く使用すると、小さな誤差が溜まって、文字の形を成さなくなってしまう。~ なので、なるべく左右のタイヤが別の動きをしないような経路を考えた (例)habayose関数 同時実行を避けることで、移動に正確性を出した -最初はペンをモーターに直接付けて、下ろす、というものにしようとしたが、その場合ペン先が離れてしまい、トルクをかけないと十分な筆圧を得られなかった。~ なので、平行四辺形の長辺にペンを付け、上げ下げを行うようにした この機構はペンに繋がる棒が近いので、トルクが低くても動かすことができた -タイヤのガタの影響を無くすため、滑り棒で支えるようにした。 -角度指定で動かすプログラムは2つ同時に動かないので、時間で動かすことにした *結果 [#yfb5248f] &ref(2018a/Member/Kkun/Mission1/fig1.jpg,50%,結果); このような文字をかくことができた。 -文字の始めが震えてしまっているのは、プログラムを同時に実行してもタイムラグにより、左右のモーターが同時には動き始めないためである -指定した距離を動くサブルーチンを作ったが、短い距離ならば問題ないが、長い距離を動かすと誤差が出てしまった~ 文字が斜めになってしまったのは残念だが、ちゃんと「信州」に見えるものが書けてよかった。 *考察 [#i75f5800] -支えとしてタイヤを使っている場合、方向転換した時に、タイヤのガタにより方向が変わってしまうので、今後も滑り棒を使って制作していきたい~ -角度指定で回転するプログラムは同時実行できないと分かり、これは、次回のロボットでも注意したい *まとめ [#tb95a9fa] 滑り棒で支えるような形のロボットを作ったが、紙の端に引っかかったり、誤差が大きくなってしまうなど色々な課題が発生した~ 無限軌道があれば、絶対座標を組んで、「A点からB点までの直線を引く」というプログラムを書きたかった~ XY方式では、よりきれいなものが書けたであろうが、この車型のものでも、満足のいく結果が得られた。 *プログラム [#h3ce703a] // タイヤ 1回転で 17.5cm // タイヤ同士の距離 17cm #define PA 75 // Aの規定の出力 #define PB 75 // Bの規定の出力 #define PC 75 // Cの規定の出力 #define CM (750/35) // 1cm進む時に、タイヤが回る角度 #define WT 100 // 1cm進む時の待機時間 前進関数 前進関数~ 引数 x で移動距離をcm単位で指定する。 void FWD(int x) { #if 1 RotateMotorEx(OUT_AC, 30, -x * CM, 0, true, true); Wait(100); #else OnRevSync(OUT_AC, 30, 0); Wait(x * 10 * WT); Off(OUT_AC); Wait(100); #endif } 後退関数~ 引数 x で移動距離をcm単位で指定する。 void REV(int x) { #if 1 RotateMotorEx(OUT_AC, 30, x * CM, 0, true, true); Wait(100); #else OnFwdSync(OUT_AC, 40, 0); Wait(x * 10 * WT); Off(OUT_AC); Wait(100); #endif } 左に90°回る void turnL90() { RotateMotorEx(OUT_AC, 30, 235, 100, true, true); Wait(200); } 右に90°回る void turnR90() { RotateMotorEx(OUT_AC, 30, -235, -100, true, true); Wait(200); } 信地旋回(右)~ 引数 x で指定した角度だけ右に回る 単位は 度 void turnR(int x) { RotateMotorEx(OUT_AC, 30, x * 235 / 90, -100, true, true); Wait(200); } 信地旋回(左)~ 引数 x で指定した角度だけ左に回る 単位は 度 void turnL(int x) { RotateMotorEx(OUT_AC, 30, x * 235 / 90, 100, true, true); Wait(200); } 幅寄せ関数~ 引数 x cm分だけ、右/左に幅寄せする~ 精度が悪かったため、一般化することが出来なかった。~ よって、予め採取した値を使用している #define HABA1 70 #define HABA2 100 #define HABA3 130 #define HABA4 161 #define HABA5 178 #define HABA6 195 void habayoseR(int x) { int para; if (x == 1) para = HABA1; else if (x == 2) para = HABA2; else if (x == 3) para = HABA3; else if (x == 4) para = HABA4; else if (x == 5) para = HABA5; else if (x == 6) para = HABA6; else return; RotateMotor(OUT_C, 30, para); RotateMotor(OUT_A, 30, para); RotateMotor(OUT_C, 30, -para); RotateMotor(OUT_A, 30, -(para * 103 / 100)); Wait(200); } void habayoseL(int x) { int para; if (x == 1) para = HABA1; else if (x == 2) para = HABA2; else if (x == 3) para = HABA3; else if (x == 4) para = HABA4; else if (x == 5) para = HABA5; else if (x == 6) para = HABA6; else return; RotateMotor(OUT_A, 30, para); RotateMotor(OUT_C, 30, para); RotateMotor(OUT_A, 30, -para); RotateMotor(OUT_C, 30, -para); Wait(200); } ペンを下げる void pen_down() { RotateMotor(OUT_B, 40, -20); Wait(100); } ペンを上げる void pen_up() { RotateMotor(OUT_B, 40, 20); Wait(100); } 横棒を書く関数(不使用)~ ロボットが横移動できないため、半径の大きな弧で、疑似的に横棒を書いている void yokobou(int x) { RotateMotor(OUT_A, 25, -x * 10); Wait(100); pen_down(); RotateMotor(OUT_A, 25, x * 10); Wait(100); RotateMotor(OUT_C, 25, -x * 10); Wait(100); pen_up(); RotateMotor(OUT_C, 25, x * 10); Wait(100); } 縦棒を書く関数~ 引数 x cmで移動距離を指定している。 void tatebou(int x) { pen_down(); RotateMotorEx(OUT_AC, 20, x * CM, 0, true, true); Wait(100); pen_up(); } 「信」を書く関数~ さきに横線を5本書いて、次に90°回転し、縦線を4本書く。~ 1画目の斜め線は、この関数では書いていない。 void draw_shin() { tatebou(6); habayoseR(2); FWD(5); tatebou(4); habayoseR(2); FWD(4); tatebou(4); habayoseR(2); FWD(4); tatebou(4); habayoseR(4); FWD(4); tatebou(4); turnL90(); REV(10); turnR90(); FWD(10); turnL90(); tatebou(8); habayoseR(6); FWD(9); tatebou(1); habayoseL(2); REV(4); tatebou(4); FWD(4); habayoseR(4); tatebou(4); } 「州」を書く関数~ 書き順通りに書いた void draw_shu() { REV(3); tatebou(2); habayoseR(2); FWD(5); tatebou(8); habayoseR(2); FWD(5); tatebou(2); habayoseR(2); FWD(5); tatebou(8); habayoseR(2); FWD(5); tatebou(2); habayoseR(2); FWD(5); tatebou(8); } メイン関数~ 「信」を書いてから、「州」を書くが、「信」の1画目の斜め線は、「州」を書き終わった後に書いている。~ これは、回転関数の精度が悪いため、回転関数の呼び出しを少なくしたかったためである。 task main() { pen_up(); draw_shin(); habayoseL(6); REV(5); draw_shu(); FWD(42); turnR(60); REV(22); tatebou(5); }