- 追加された行はこの色です。
- 削除された行はこの色です。
#author("2019-11-09T11:13:29+09:00","atsu","atsu")
* 課題1 [#pb35834d]
#author("2019-11-09T13:24:47+09:00","atsu","atsu")
#contents
* 課題1 [#n753e1da]
* 課題1 [#n0c06f04]
[[2019b/Mission1]]を参照してください。
* ロボットの説明 [#id3a57eb]
* ロボットの説明 [#aa277229]
* ロボットの説明 [#u8a6abca]
x軸とy軸、ペンの上げ下げにそれぞれ1つずつモーターを配置したロボットを制作した。
x軸とy軸、ペンの上げ下げにそれぞれ1つずつモーターを配置したロボットを制作した。なぜなら、プログラムが簡単そうだったからだ。
タイヤがあると誤差が大きくなると考えたので、物理的にモーターとつながっている構造
にしたいと思った。
タイヤがあると誤差が大きくなると考えたので、物理的にモーターとつながっている構造にしたいと思った。そこで、スライダクランク機構(参考[http://www.museum.kyoto-u.ac.jp/collection/materials/mech4.html]])を用いて x軸 , y軸 の動きを作ることにした。
x軸 , y軸はこのようになった。2つの軸には鏡で映しただけで同じ構造のものを用いた。
ペンの取付部のパーツはこのようにした。
ペンの取り付けパーツはそれぞれの軸の上に乗っかっているだけである。軸に垂直な方向にしか動かないように軸上のスリットのところに置く。
ペンの上げ下げは、以下の写真のモーターでペン取り付けパーツの端を押すことで実現させる。
* プログラムの説明 [#x63e1db5]
* プログラムの説明 [#g1b0ecc6]
今回は、サーボモーターの機能を使用した。
** 今回使用したプログラム [#fb136830]
** 今回使用したプログラム [#y90b608a]
#define SPEED 10
#define P 40
#define I 40
#define D 90
#define gf(x,y,z) gt(x-log_x,y-log_y,z);log_x=x;log_y=y;
#define pu OnFwd(OUT_A,20);Wait(500);Off(OUT_A); //ペン上げ
#define pd OnFwd(OUT_A,-SPEED);Wait(300);Off(OUT_A);Wait(600); //ペン下げ
#define gh gf(0,0,1); //ホームポジション( 0 , 0 )に戻る
sub gt(float x,float y,float z) //(行き先の座標 , 繰り返しの回数)
{
const float axis = 100.0; //軸
const int rep = z; //繰り返し回数
const float rotation = 180.0; //軸を端から端まで動かすのに必要な角度
const float correction = 0.5; //補正
float angle_x = ((rotation/axis)*x)/rep + sign(x)*correction;
float angle_y = ((rotation/axis)*y)/rep + sign(y)*correction;
repeat(rep)
{
//RotateMotor(OUT_B,SPEED,angle_x);
RotateMotorPID(OUT_B,SPEED,angle_x,P,I,D);
//RotateMotor(OUT_C,SPEED,angle_y);
RotateMotorPID(OUT_C,SPEED,angle_y,P,I,D);
}
Wait(400);
}
task main()
{
ResetTachoCount(OUT_BC);
float log_x = 0;
float log_y = 0;
//輪郭
pu;
gf(0.0,100.0,2);
pd;
gf(0.0,35.0,1);
gf(35.0,0.0,30);
gf(45.0,0.0,1);
gf(100.0,35.0,30);
gf(100.0,100.0,1);
gf(0.0,100.0,1);
pu;
//メガネ
gf(30.0,50.0,2);
pd;
gf(50.0,50.0,1);
gf(50.0,40.0,1);
gf(25.0,40.0,1);
gf(25.0,60.0,1);
pu;
gf(50.0,45.0,1);
pd;
gf(60.0,45.0,1);
pu;
gf(60.0,55.0,2);
pd;
gf(80.0,55.0,1);
gf(80.0,40.0,1);
gf(52.0,40.0,1);
gf(52.0,55.0,1);
pu;
//鼻
gf(45.0,35.0,2);
pd;
gf(40.0,25.0,10);
gf(50.0,28.0,1);
pu;
//口
gf(30.0,15.0,2);
pd;
gf(60.0,15.0,2);
pu;
gh;
}
** ペンの上げ下げ [#va80b026]
** ペンの上げ下げ [#q181123d]
マクロを使用して、pu = pen up , pd = pen down として指定した。
#define pu OnFwd(OUT_A,20);Wait(500);Off(OUT_A);
#define pd OnFwd(OUT_A,-SPEED);Wait(300);Off(OUT_A);Wait(600);
** ペンの移動 [#ub93e30f]
** ペンの移動 [#x4f0a809]
指定した座標と今いる座標を直線で結んでくれるような関数を "define" と "sub" を用いて作った。
#define gf(x,y,z) gt(x-log_x,y-log_y,z);log_x=x;log_y=y;
sub gt(float x,float y,float z) //(行き先の座標 , 繰り返しの回数)
{
const float axis = 100.0; //軸
const int rep = z; //繰り返し回数
const float rotation = 180.0; //軸を端から端まで動かすのに必要な角度
const float correction = 0.5; //補正
float angle_x = ((rotation/axis)*x)/rep + sign(x)*correction;
float angle_y = ((rotation/axis)*y)/rep + sign(y)*correction;
repeat(rep)
{
//RotateMotor(OUT_B,SPEED,angle_x);
RotateMotorPID(OUT_B,SPEED,angle_x,P,I,D);
//RotateMotor(OUT_C,SPEED,angle_y);
RotateMotorPID(OUT_C,SPEED,angle_y,P,I,D);
}
Wait(400);
}
task main()
{
float log_x = 0;
float log_y = 0;
}
これにより、以下のように書くことで、指定した座標まで動かすことができる。"sub"だけでは相対的な座標で動いてしまうので、"log_x","log_y"という変数を用意して、直前に指定された座標を記憶しておくことで、絶対的な座標として動かすことが可能になる。
この関数は以下のようにして使う。
gf(移動先の x座標 , 移動先の y座標 , 繰り返し回数)
ここでは、x軸 y軸ともに 100 メモリとして計算した。
NXTでは、2つのモーターを同時に違う出力で動かすことができない。そのため、斜めの線をひくことができない。そこで、階段を書くような感じで、x軸 y軸方向に少しずつ動かして斜めの線を書くようにした。ここでいう階段の数というのが関数の引数の中にある繰り返し回数である。繰り返し回数を増やすほどなめらかな線を描ける。