[[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);
 }

トップ   編集 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS