2016b/Member/ta.kashi/Mission1
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
検索
|
最終更新
|
ヘルプ
|
ログイン
]
開始行:
[[2016b/Member]]
#contents
* 概要 [#k332b24c]
今回の[[課題:http://yakushi.shinshu-u.ac.jp/robotics/?2016b%2FMission1]]は書道ロボットである.
一般的なローバーにペンをつけただけでは,H/Wは簡単でもS/Wで困難を極めるので,縦軸を動くロボットと横軸を動くロボット,そしてペンの昇降装置をつくり,それぞれに役割を分担させることにした.こうすることでコーディングが簡単になる.
加えて,このタイプのロボットであれば(理論上は)描画する線の角度なども,バッテリーの電圧に依存することなく常に一定になる(但し最終的な文字の大きさは変化する).
* ハードウェアについて [#fe7dae33]
#ref(2016b/Member/ta.kashi/Mission1/Fig_001.JPG,80%,完成したロボット)
もともとは自動車工場などで稼働しているような「アームロボット」型のものを作る予定だっただが,部品点数の少なさやS/Wが複雑になりすぎることが判明したので断念した.
かわって,冒頭で記した通り,縦軸(以降Y軸と呼ぶ)を動くローバーロボットに高架を接続し,その上に,横軸(以降X軸と呼ぶ)を動くローバーロボットを走らせる.そのローバーロボットにペンの昇降を制御するアームを取り付け,Y軸移動,X軸移動,ペンの昇降をそれぞれ独立して制御するようにした.
** Y軸制御ロボット [#w18d7065]
#ref(2016b/Member/ta.kashi/Mission1/Fig_002.JPG,80%,Y軸制御ロボット)
写真の通り,基本的なローバーロボットに高架を接続したものである.
ローバーロボット本体に関しては途中で曲がらずに,できるかぎり直線的に移動する必要があり,また,高架にアーム付きローバーロボット(重い)が乗ることを考え,できるだけ安定する必要がある.そのためにホイールスペースをできるだけ長くとった.
また,ローバーロボットと反対側を支える支柱はできるだけ滑らかに動作し,引っかかることのないようにしなければならなかったため,あえてタイヤ(ゴム)を外したが,あまり改善されなかった.
高架部分は長いブロックを使用し,重さに耐えられるようにした.途中つなぎ目部分で段差があるが,動作に支障はなかった.
** X軸制御/ペン昇降ロボット [#bf60eca9]
#ref(2016b/Member/ta.kashi/Mission1/Fig_003.JPG,80%,X軸制御/ペン昇降ロボット)
基本的なローバーロボットであるが,車輪の幅が高架の幅と一致するようになっている.また,動作時の振動や通信ケーブルのねじれによって脱輪することのないように,ロボット下側にガイドを取り付けた.
#ref(2016b/Member/ta.kashi/Mission1/Fig_004.JPG,80%,ガイド)
Y軸制御ロボットを作った段階で部品が不足していたため,アーム部分の取り付けにはかなり無理をしている(ただし動作に支障はなかった).
当初は,ペンの昇降は"4211510"と呼ばれる部品(ねじ状の部品)を使い,エレベーターのように行う予定であったが,部品の不足と重量の問題で断念し,かわりにモーターにペンを取り付けるだけのシンプルな構成にした.これによって部品を大幅に節約できるが,ペン先を紙面に対して垂直に当てられないため,ペンを降ろす際の力加減によっては,これが動作時の微妙なずれの原因となるようである.これはS/Wによるキャリブレーションで解決している.
* ソフトウェアについて [#x786cf6a]
課題では「7画以上の漢字」を書く必要があるが,H/Wの仕様上斜めに線を描くことが難しい(実際に試したが無視できないほどの誤差が生じてしまった)ので,極力水平・垂直な線の多い文字を選ぶ必要がある.今回は「車」「豆」という文字を選んだ.
以下がそのコード(「車」)である.結果は[[こちら>#r55c21f1]]を参照.
//OUT_A -> Y軸移動(縦)
//OUT_B -> X軸移動(横)
//OUT_C -> Z軸移動(ペン)
#define MP_XY 20 //モーターの強さは20に固定
#define MP_Z 10 //ただしペンの昇降は弱めにする
sub X_ML(int time) //X軸左方向
{
OnRev(OUT_B,MP_XY);
Wait(time);
Off(OUT_ABC);Wait(1000);
}
sub X_MR(int time) //X軸右方向
{
OnFwd(OUT_B,MP_XY);
Wait(time);
Off(OUT_ABC);Wait(1000);
}
sub Y_UP(int time) //Y軸上方向
{
OnRev(OUT_A,MP_XY);Wait(time);
Off(OUT_ABC);Wait(1000);
}
sub Y_DWN(int time) //Y軸下方向
{
OnFwd(OUT_A,MP_XY);Wait(time);
Off(OUT_ABC);Wait(1000);
}
sub Z_UP() //ペンをあげる
{
RotateMotor(OUT_C,MP_Z,-20);
Off(OUT_ABC);Wait(1000);
}
sub Z_DWN() //ペンをおろす
{
RotateMotor(OUT_C,MP_Z,20);
Off(OUT_ABC);Wait(1000);
}
task main()
{
/*
"Z_DWN()"から"Z_UP()"までの動作で線を描画する.
それ以外の動作は移動のみで,実際に描画はしない.
ペン先を紙面に当てた状態で実行すること.
*/
Z_UP();
Z_DWN();X_MR(1000);Z_UP();
Y_DWN(200);
Z_DWN();X_ML(1000);Y_DWN(600);Z_UP();
Y_UP(600);X_MR(1000);
Z_DWN();Y_DWN(600);Z_UP();
Y_UP(400);
Z_DWN();X_ML(1200);Z_UP();
Y_DWN(400);
Z_DWN();X_MR(1200);Z_UP();
Y_DWN(300);
Z_DWN();X_ML(1200);Z_UP();
Y_UP(1500);X_MR(600);
Z_DWN();Y_DWN(1600);Z_UP();
}
** モーターの対応 [#nf95a1f0]
//OUT_A -> Y軸移動(縦)
//OUT_B -> X軸移動(横)
//OUT_C -> Z軸移動(ペン)
これは,それぞれの出力が対応するモーターを示している(コメント).
** モーターのトルクを定義 [#d3f0263b]
#define MP_XY 20 //モーターの強さは20に固定
#define MP_Z 10 //ただしペンの昇降は弱めにする
これは,モーターのトルクをマクロ置換している(MP=Moter Power).
H/Wの動作,特に,ペンの昇降についてはゆっくりと行わないと誤差の原因となる.X軸制御/ペン昇降ロボットについては,あまり高速に動作させると高架から脱輪することもあった.
** 各種動作の定義 [#i2b29751]
sub X_ML(int time) //X軸左方向
{
OnRev(OUT_B,MP_XY);
Wait(time);
Off(OUT_ABC);Wait(1000);
}
sub X_MR(int time) //X軸右方向
{
OnFwd(OUT_B,MP_XY);
Wait(time);
Off(OUT_ABC);Wait(1000);
}
これは,X軸方向の移動をsubroutineとして定義したものである.
動作時間(=移動距離)を引数としている.動作後には1秒間静止するようにしている.これは,振動によるズレを防ぐためである.
以下も同様
sub Y_UP(int time) //Y軸上方向
{
OnRev(OUT_A,MP_XY);Wait(time);
Off(OUT_ABC);Wait(1000);
}
sub Y_DWN(int time) //Y軸下方向
{
OnFwd(OUT_A,MP_XY);Wait(time);
Off(OUT_ABC);Wait(1000);
}
sub Z_UP() //ペンをあげる
{
RotateMotor(OUT_C,MP_Z,-20);
Off(OUT_ABC);Wait(1000);
}
sub Z_DWN() //ペンをおろす
{
RotateMotor(OUT_C,MP_Z,20);
Off(OUT_ABC);Wait(1000);
}
ペンの昇降についてはOnFwd(OnRev)ではなく,回転の角度を指定できるRotateMotorを使用した.
** task main() [#s7e23c40]
task main()
{
/*
"Z_DWN()"から"Z_UP()"までの動作で線を描画する.
それ以外の動作は移動のみで,実際に描画はしない.
ペン先を紙面に当てた状態で実行すること.
*/
Z_UP();
Z_DWN();X_MR(1000);Z_UP();
Y_DWN(200);
Z_DWN();X_ML(1000);Y_DWN(600);Z_UP();
Y_UP(600);X_MR(1000);
Z_DWN();Y_DWN(600);Z_UP();
Y_UP(400);
Z_DWN();X_ML(1200);Z_UP();
Y_DWN(400);
Z_DWN();X_MR(1200);Z_UP();
Y_DWN(300);
Z_DWN();X_ML(1200);Z_UP();
Y_UP(1500);X_MR(600);
Z_DWN();Y_DWN(1600);Z_UP();
}
最初はペン先を紙面に当てた状態にしておく.これは,線を描く際に確実にペン先を紙面に当てるためである.プログラムを実行すると同時にペン先は指定した角度(20度)上昇する.
以降,Z_DWN()でペン先が紙面に当たり,Z_UP()でペン先が離れるわけなので,Z_DWN()からZ_UP()で挟まれた部分は実際に紙面に描画され,それ以外は描画されない,ただの移動となる(ペン先は空中を移動する).
注意する点は,特にY軸方向に描画する際に,図のように手前方向へ移動するのはOKだが,奥方向はNGである(線がかすれてしまう).
#ref(2016b/Member/ta.kashi/Mission1/Fig_005.JPG,80%,ペン先の移動)
移動量が一致しないところもあるが,これは実際に紙面に描画する際のズレを考慮した結果である.
** 別のコード [#a97277bb]
「車」以外にも「豆」という漢字も書くことができた.結果は[[こちら>#ia154883]]を参照.
//OUT_A _> Y軸移動(縦)
//OUT_B _> X軸移動(横)
//OUT_C _> Z軸移動(ペン)
#define MP_XY 20 //モーターの強さは20に固定
#define MP_Z 10 //ただしペンの昇降は弱めにする
sub X_ML(int time) //X軸左方向き
{
OnRev(OUT_B,MP_XY);
Wait(time);
Off(OUT_ABC);Wait(1000);
}
sub X_MR(int time) //X軸右方向
{
OnFwd(OUT_B,MP_XY);
Wait(time);
Off(OUT_ABC);Wait(1000);
}
sub Y_UP(int time) //Y軸上方向
{
OnRev(OUT_A,MP_XY);Wait(time);
Off(OUT_ABC);Wait(1000);
}
sub Y_DWN(int time) //Y軸下方向
{
OnFwd(OUT_A,MP_XY);Wait(time);
Off(OUT_ABC);Wait(1000);
}
sub Z_UP() //ペンをあげる
{
RotateMotor(OUT_C,MP_Z,-20);
Off(OUT_ABC);Wait(1000);
}
sub Z_DWN() //ペンをおろす
{
RotateMotor(OUT_C,MP_Z,20);
Off(OUT_ABC);Wait(1000);
}
task main()
{
/*
"Z_DWN()"から"Z_UP()"までの動作で線を描画する.
それ以外の動作は移動のみで,実際に描画はしない.
ペン先を紙面に当てた状態で実行すること.
*/
Z_UP();
Z_DWN();X_MR(1000);Z_UP();
Y_DWN(300);X_ML(300);
Z_DWN();X_ML(700);Y_DWN(400);X_MR(800);Z_UP();
Y_UP(400);
Z_DWN();Y_DWN(400);Z_UP();
X_ML(600);Y_DWN(200);
Z_DWN();Y_DWN(400);Z_UP();
X_MR(500);Y_UP(400);
Z_DWN();Y_DWN(400);Z_UP();
X_ML(800);Y_DWN(200);
Z_DWN();X_MR(1200);Z_UP();
}
* プリンターのような動作も [#l8b06310]
インクジェットプリンターのように動作させ,文字(やイラスト)を描画することもできる.この場合,Y軸制御ロボットがプリンターの紙送り機能を,X軸制御/ペン昇降ロボットがプリンターのヘッドの役割をなす.
この場合,斜めの線や曲線を多用した文字でも容易に描写できる.
下図のように,文字を20x20のドットに分割して考える.
#ref(2016b/Member/ta.kashi/Mission1/Fig_006.JPG,80%,デザイン)
以下がそのコードである.結果は[[こちら>#c65845b7]]を参照.
//OUT_A _> Y軸移動(縦)
//OUT_B _> X軸移動(横)
//OUT_C _> Z軸移動(ペン)
#define MP_XY 20 //モーターの強さは20に固定
#define MP_Z 10 //ただしペンの昇降は弱めにする
sub X_ML(int time) //X軸左方向に走査
{
OnRev(OUT_B,MP_XY);
Wait(time);
Off(OUT_ABC);Wait(1000);
}
sub X_MR(int time) //X軸右方向に走査
{
OnFwd(OUT_B,MP_XY);
Wait(time);
Off(OUT_ABC);Wait(1000);
}
sub Y_DWN() //Y軸方向に1単位進む
{
OnFwd(OUT_A,MP_XY);Wait(200);
Off(OUT_ABC);Wait(1000);
}
sub Z_UP() //ペンをあげる
{
RotateMotor(OUT_C,MP_Z,-20);
Off(OUT_ABC);Wait(1000);
}
sub Z_DWN() //ペンをおろす
{
RotateMotor(OUT_C,MP_Z,20);
Off(OUT_ABC);Wait(1000);
}
task main()
{
Z_UP();
//1行目
X_ML(2050);
Y_DWN();
//2行目
X_MR(150);
Z_DWN();X_MR(1800);Z_UP();
X_MR(100);
Y_DWN();
//3行目
X_ML(150);
Z_DWN();X_ML(1800);Z_UP();
X_ML(100);
Y_DWN();
//4行目
X_MR(50);
Z_DWN();X_MR(200);Z_UP();
X_MR(1400);
Z_DWN();X_MR(200);Z_UP();
X_MR(100);
Y_DWN();
//5行目
X_ML(1350);
Z_DWN();X_ML(200);Z_UP();
X_ML(500);
Y_DWN();
//6行目
X_MR(450);
Z_DWN();X_MR(1100);Z_UP();
X_MR(400);
Y_DWN();
//7行目
X_ML(450);
Z_DWN();X_ML(1100);Z_UP();
X_ML(400);
Y_DWN();
//8行目
X_MR(450);
Z_DWN();X_MR(200);Z_UP();
X_MR(1300);
Y_DWN();
//9行目
X_ML(1350);
Z_DWN();X_ML(200);Z_UP();
X_ML(500);
Y_DWN();
//10行目
X_MR(450);
Z_DWN();X_MR(200);Z_UP();
X_MR(1300);
Y_DWN();
//11行目
X_ML(450);
Z_DWN();X_ML(1100);Z_UP();
X_ML(400);
Y_DWN();
//12行目
X_MR(450);
Z_DWN();X_MR(1100);Z_UP();
X_MR(400);
Y_DWN();
//13行目
X_ML(450);
Z_DWN();X_ML(200);Z_UP();
X_ML(700);
Z_DWN();X_ML(200);Z_UP();
X_ML(500);
Y_DWN();
//14行目
X_MR(1350);
Z_DWN();X_MR(200);Z_UP();
X_MR(400);
Y_DWN();
//15行目
X_ML(250);
Z_DWN(),X_ML(1600);Z_UP();
X_ML(200);
Y_DWN();
//16行目
X_MR(150);
Z_DWN(),X_MR(1600);Z_UP();
X_MR(200);
Y_DWN();
//17行目
X_ML(450);
Z_DWN(),X_ML(200);Z_UP();
X_ML(1400);
Y_DWN();
//18行目
X_MR(750);
Z_DWN(),X_MR(800);Z_UP();
X_MR(400);
Y_DWN();
//19行目
X_ML(450);
Z_DWN(),X_ML(800);Z_UP();
X_ML(800);
Y_DWN();
//20行目
X_MR(1950);
}
* 結果 [#g0d32be8]
** 「豆」 [#ia154883]
#ref(2016b/Member/ta.kashi/Mission1/Fig_007.JPG,80%,デザイン)
** 「車」 [#r55c21f1]
#ref(2016b/Member/ta.kashi/Mission1/Fig_008.JPG,80%,デザイン)
** 「写」 [#c65845b7]
#ref(2016b/Member/ta.kashi/Mission1/Fig_009.JPG,80%,デザイン)
走査線の間隔が広いのでわかりにくいが,以下のように「写」と描画されている.Y軸の間隔をもっと小さくすればよいが,そこまで細かい制御はできなかった.
#ref(2016b/Member/ta.kashi/Mission1/Fig_010.JPG,80%,デザイン)
* 感想と反省 [#s0168e40]
mindstormシリーズは,実は小学生の時に使ったことがあり,簡単な茶運び人形程度のものであれば作ったことがあった.しかしその際はGUIでコードの記述を行っていたのに対し,今回はCライクな言語で記述する必要があった.GUIに比べて動作が視覚的に確認しづらいという点では苦労したが,プログラミングに対する理解が深まった.
H/Wでは,特に動作毎の微妙な誤差に悩まされたが,それも部品の調整やS/Wの調整で減らすことができた.
終了行:
[[2016b/Member]]
#contents
* 概要 [#k332b24c]
今回の[[課題:http://yakushi.shinshu-u.ac.jp/robotics/?2016b%2FMission1]]は書道ロボットである.
一般的なローバーにペンをつけただけでは,H/Wは簡単でもS/Wで困難を極めるので,縦軸を動くロボットと横軸を動くロボット,そしてペンの昇降装置をつくり,それぞれに役割を分担させることにした.こうすることでコーディングが簡単になる.
加えて,このタイプのロボットであれば(理論上は)描画する線の角度なども,バッテリーの電圧に依存することなく常に一定になる(但し最終的な文字の大きさは変化する).
* ハードウェアについて [#fe7dae33]
#ref(2016b/Member/ta.kashi/Mission1/Fig_001.JPG,80%,完成したロボット)
もともとは自動車工場などで稼働しているような「アームロボット」型のものを作る予定だっただが,部品点数の少なさやS/Wが複雑になりすぎることが判明したので断念した.
かわって,冒頭で記した通り,縦軸(以降Y軸と呼ぶ)を動くローバーロボットに高架を接続し,その上に,横軸(以降X軸と呼ぶ)を動くローバーロボットを走らせる.そのローバーロボットにペンの昇降を制御するアームを取り付け,Y軸移動,X軸移動,ペンの昇降をそれぞれ独立して制御するようにした.
** Y軸制御ロボット [#w18d7065]
#ref(2016b/Member/ta.kashi/Mission1/Fig_002.JPG,80%,Y軸制御ロボット)
写真の通り,基本的なローバーロボットに高架を接続したものである.
ローバーロボット本体に関しては途中で曲がらずに,できるかぎり直線的に移動する必要があり,また,高架にアーム付きローバーロボット(重い)が乗ることを考え,できるだけ安定する必要がある.そのためにホイールスペースをできるだけ長くとった.
また,ローバーロボットと反対側を支える支柱はできるだけ滑らかに動作し,引っかかることのないようにしなければならなかったため,あえてタイヤ(ゴム)を外したが,あまり改善されなかった.
高架部分は長いブロックを使用し,重さに耐えられるようにした.途中つなぎ目部分で段差があるが,動作に支障はなかった.
** X軸制御/ペン昇降ロボット [#bf60eca9]
#ref(2016b/Member/ta.kashi/Mission1/Fig_003.JPG,80%,X軸制御/ペン昇降ロボット)
基本的なローバーロボットであるが,車輪の幅が高架の幅と一致するようになっている.また,動作時の振動や通信ケーブルのねじれによって脱輪することのないように,ロボット下側にガイドを取り付けた.
#ref(2016b/Member/ta.kashi/Mission1/Fig_004.JPG,80%,ガイド)
Y軸制御ロボットを作った段階で部品が不足していたため,アーム部分の取り付けにはかなり無理をしている(ただし動作に支障はなかった).
当初は,ペンの昇降は"4211510"と呼ばれる部品(ねじ状の部品)を使い,エレベーターのように行う予定であったが,部品の不足と重量の問題で断念し,かわりにモーターにペンを取り付けるだけのシンプルな構成にした.これによって部品を大幅に節約できるが,ペン先を紙面に対して垂直に当てられないため,ペンを降ろす際の力加減によっては,これが動作時の微妙なずれの原因となるようである.これはS/Wによるキャリブレーションで解決している.
* ソフトウェアについて [#x786cf6a]
課題では「7画以上の漢字」を書く必要があるが,H/Wの仕様上斜めに線を描くことが難しい(実際に試したが無視できないほどの誤差が生じてしまった)ので,極力水平・垂直な線の多い文字を選ぶ必要がある.今回は「車」「豆」という文字を選んだ.
以下がそのコード(「車」)である.結果は[[こちら>#r55c21f1]]を参照.
//OUT_A -> Y軸移動(縦)
//OUT_B -> X軸移動(横)
//OUT_C -> Z軸移動(ペン)
#define MP_XY 20 //モーターの強さは20に固定
#define MP_Z 10 //ただしペンの昇降は弱めにする
sub X_ML(int time) //X軸左方向
{
OnRev(OUT_B,MP_XY);
Wait(time);
Off(OUT_ABC);Wait(1000);
}
sub X_MR(int time) //X軸右方向
{
OnFwd(OUT_B,MP_XY);
Wait(time);
Off(OUT_ABC);Wait(1000);
}
sub Y_UP(int time) //Y軸上方向
{
OnRev(OUT_A,MP_XY);Wait(time);
Off(OUT_ABC);Wait(1000);
}
sub Y_DWN(int time) //Y軸下方向
{
OnFwd(OUT_A,MP_XY);Wait(time);
Off(OUT_ABC);Wait(1000);
}
sub Z_UP() //ペンをあげる
{
RotateMotor(OUT_C,MP_Z,-20);
Off(OUT_ABC);Wait(1000);
}
sub Z_DWN() //ペンをおろす
{
RotateMotor(OUT_C,MP_Z,20);
Off(OUT_ABC);Wait(1000);
}
task main()
{
/*
"Z_DWN()"から"Z_UP()"までの動作で線を描画する.
それ以外の動作は移動のみで,実際に描画はしない.
ペン先を紙面に当てた状態で実行すること.
*/
Z_UP();
Z_DWN();X_MR(1000);Z_UP();
Y_DWN(200);
Z_DWN();X_ML(1000);Y_DWN(600);Z_UP();
Y_UP(600);X_MR(1000);
Z_DWN();Y_DWN(600);Z_UP();
Y_UP(400);
Z_DWN();X_ML(1200);Z_UP();
Y_DWN(400);
Z_DWN();X_MR(1200);Z_UP();
Y_DWN(300);
Z_DWN();X_ML(1200);Z_UP();
Y_UP(1500);X_MR(600);
Z_DWN();Y_DWN(1600);Z_UP();
}
** モーターの対応 [#nf95a1f0]
//OUT_A -> Y軸移動(縦)
//OUT_B -> X軸移動(横)
//OUT_C -> Z軸移動(ペン)
これは,それぞれの出力が対応するモーターを示している(コメント).
** モーターのトルクを定義 [#d3f0263b]
#define MP_XY 20 //モーターの強さは20に固定
#define MP_Z 10 //ただしペンの昇降は弱めにする
これは,モーターのトルクをマクロ置換している(MP=Moter Power).
H/Wの動作,特に,ペンの昇降についてはゆっくりと行わないと誤差の原因となる.X軸制御/ペン昇降ロボットについては,あまり高速に動作させると高架から脱輪することもあった.
** 各種動作の定義 [#i2b29751]
sub X_ML(int time) //X軸左方向
{
OnRev(OUT_B,MP_XY);
Wait(time);
Off(OUT_ABC);Wait(1000);
}
sub X_MR(int time) //X軸右方向
{
OnFwd(OUT_B,MP_XY);
Wait(time);
Off(OUT_ABC);Wait(1000);
}
これは,X軸方向の移動をsubroutineとして定義したものである.
動作時間(=移動距離)を引数としている.動作後には1秒間静止するようにしている.これは,振動によるズレを防ぐためである.
以下も同様
sub Y_UP(int time) //Y軸上方向
{
OnRev(OUT_A,MP_XY);Wait(time);
Off(OUT_ABC);Wait(1000);
}
sub Y_DWN(int time) //Y軸下方向
{
OnFwd(OUT_A,MP_XY);Wait(time);
Off(OUT_ABC);Wait(1000);
}
sub Z_UP() //ペンをあげる
{
RotateMotor(OUT_C,MP_Z,-20);
Off(OUT_ABC);Wait(1000);
}
sub Z_DWN() //ペンをおろす
{
RotateMotor(OUT_C,MP_Z,20);
Off(OUT_ABC);Wait(1000);
}
ペンの昇降についてはOnFwd(OnRev)ではなく,回転の角度を指定できるRotateMotorを使用した.
** task main() [#s7e23c40]
task main()
{
/*
"Z_DWN()"から"Z_UP()"までの動作で線を描画する.
それ以外の動作は移動のみで,実際に描画はしない.
ペン先を紙面に当てた状態で実行すること.
*/
Z_UP();
Z_DWN();X_MR(1000);Z_UP();
Y_DWN(200);
Z_DWN();X_ML(1000);Y_DWN(600);Z_UP();
Y_UP(600);X_MR(1000);
Z_DWN();Y_DWN(600);Z_UP();
Y_UP(400);
Z_DWN();X_ML(1200);Z_UP();
Y_DWN(400);
Z_DWN();X_MR(1200);Z_UP();
Y_DWN(300);
Z_DWN();X_ML(1200);Z_UP();
Y_UP(1500);X_MR(600);
Z_DWN();Y_DWN(1600);Z_UP();
}
最初はペン先を紙面に当てた状態にしておく.これは,線を描く際に確実にペン先を紙面に当てるためである.プログラムを実行すると同時にペン先は指定した角度(20度)上昇する.
以降,Z_DWN()でペン先が紙面に当たり,Z_UP()でペン先が離れるわけなので,Z_DWN()からZ_UP()で挟まれた部分は実際に紙面に描画され,それ以外は描画されない,ただの移動となる(ペン先は空中を移動する).
注意する点は,特にY軸方向に描画する際に,図のように手前方向へ移動するのはOKだが,奥方向はNGである(線がかすれてしまう).
#ref(2016b/Member/ta.kashi/Mission1/Fig_005.JPG,80%,ペン先の移動)
移動量が一致しないところもあるが,これは実際に紙面に描画する際のズレを考慮した結果である.
** 別のコード [#a97277bb]
「車」以外にも「豆」という漢字も書くことができた.結果は[[こちら>#ia154883]]を参照.
//OUT_A _> Y軸移動(縦)
//OUT_B _> X軸移動(横)
//OUT_C _> Z軸移動(ペン)
#define MP_XY 20 //モーターの強さは20に固定
#define MP_Z 10 //ただしペンの昇降は弱めにする
sub X_ML(int time) //X軸左方向き
{
OnRev(OUT_B,MP_XY);
Wait(time);
Off(OUT_ABC);Wait(1000);
}
sub X_MR(int time) //X軸右方向
{
OnFwd(OUT_B,MP_XY);
Wait(time);
Off(OUT_ABC);Wait(1000);
}
sub Y_UP(int time) //Y軸上方向
{
OnRev(OUT_A,MP_XY);Wait(time);
Off(OUT_ABC);Wait(1000);
}
sub Y_DWN(int time) //Y軸下方向
{
OnFwd(OUT_A,MP_XY);Wait(time);
Off(OUT_ABC);Wait(1000);
}
sub Z_UP() //ペンをあげる
{
RotateMotor(OUT_C,MP_Z,-20);
Off(OUT_ABC);Wait(1000);
}
sub Z_DWN() //ペンをおろす
{
RotateMotor(OUT_C,MP_Z,20);
Off(OUT_ABC);Wait(1000);
}
task main()
{
/*
"Z_DWN()"から"Z_UP()"までの動作で線を描画する.
それ以外の動作は移動のみで,実際に描画はしない.
ペン先を紙面に当てた状態で実行すること.
*/
Z_UP();
Z_DWN();X_MR(1000);Z_UP();
Y_DWN(300);X_ML(300);
Z_DWN();X_ML(700);Y_DWN(400);X_MR(800);Z_UP();
Y_UP(400);
Z_DWN();Y_DWN(400);Z_UP();
X_ML(600);Y_DWN(200);
Z_DWN();Y_DWN(400);Z_UP();
X_MR(500);Y_UP(400);
Z_DWN();Y_DWN(400);Z_UP();
X_ML(800);Y_DWN(200);
Z_DWN();X_MR(1200);Z_UP();
}
* プリンターのような動作も [#l8b06310]
インクジェットプリンターのように動作させ,文字(やイラスト)を描画することもできる.この場合,Y軸制御ロボットがプリンターの紙送り機能を,X軸制御/ペン昇降ロボットがプリンターのヘッドの役割をなす.
この場合,斜めの線や曲線を多用した文字でも容易に描写できる.
下図のように,文字を20x20のドットに分割して考える.
#ref(2016b/Member/ta.kashi/Mission1/Fig_006.JPG,80%,デザイン)
以下がそのコードである.結果は[[こちら>#c65845b7]]を参照.
//OUT_A _> Y軸移動(縦)
//OUT_B _> X軸移動(横)
//OUT_C _> Z軸移動(ペン)
#define MP_XY 20 //モーターの強さは20に固定
#define MP_Z 10 //ただしペンの昇降は弱めにする
sub X_ML(int time) //X軸左方向に走査
{
OnRev(OUT_B,MP_XY);
Wait(time);
Off(OUT_ABC);Wait(1000);
}
sub X_MR(int time) //X軸右方向に走査
{
OnFwd(OUT_B,MP_XY);
Wait(time);
Off(OUT_ABC);Wait(1000);
}
sub Y_DWN() //Y軸方向に1単位進む
{
OnFwd(OUT_A,MP_XY);Wait(200);
Off(OUT_ABC);Wait(1000);
}
sub Z_UP() //ペンをあげる
{
RotateMotor(OUT_C,MP_Z,-20);
Off(OUT_ABC);Wait(1000);
}
sub Z_DWN() //ペンをおろす
{
RotateMotor(OUT_C,MP_Z,20);
Off(OUT_ABC);Wait(1000);
}
task main()
{
Z_UP();
//1行目
X_ML(2050);
Y_DWN();
//2行目
X_MR(150);
Z_DWN();X_MR(1800);Z_UP();
X_MR(100);
Y_DWN();
//3行目
X_ML(150);
Z_DWN();X_ML(1800);Z_UP();
X_ML(100);
Y_DWN();
//4行目
X_MR(50);
Z_DWN();X_MR(200);Z_UP();
X_MR(1400);
Z_DWN();X_MR(200);Z_UP();
X_MR(100);
Y_DWN();
//5行目
X_ML(1350);
Z_DWN();X_ML(200);Z_UP();
X_ML(500);
Y_DWN();
//6行目
X_MR(450);
Z_DWN();X_MR(1100);Z_UP();
X_MR(400);
Y_DWN();
//7行目
X_ML(450);
Z_DWN();X_ML(1100);Z_UP();
X_ML(400);
Y_DWN();
//8行目
X_MR(450);
Z_DWN();X_MR(200);Z_UP();
X_MR(1300);
Y_DWN();
//9行目
X_ML(1350);
Z_DWN();X_ML(200);Z_UP();
X_ML(500);
Y_DWN();
//10行目
X_MR(450);
Z_DWN();X_MR(200);Z_UP();
X_MR(1300);
Y_DWN();
//11行目
X_ML(450);
Z_DWN();X_ML(1100);Z_UP();
X_ML(400);
Y_DWN();
//12行目
X_MR(450);
Z_DWN();X_MR(1100);Z_UP();
X_MR(400);
Y_DWN();
//13行目
X_ML(450);
Z_DWN();X_ML(200);Z_UP();
X_ML(700);
Z_DWN();X_ML(200);Z_UP();
X_ML(500);
Y_DWN();
//14行目
X_MR(1350);
Z_DWN();X_MR(200);Z_UP();
X_MR(400);
Y_DWN();
//15行目
X_ML(250);
Z_DWN(),X_ML(1600);Z_UP();
X_ML(200);
Y_DWN();
//16行目
X_MR(150);
Z_DWN(),X_MR(1600);Z_UP();
X_MR(200);
Y_DWN();
//17行目
X_ML(450);
Z_DWN(),X_ML(200);Z_UP();
X_ML(1400);
Y_DWN();
//18行目
X_MR(750);
Z_DWN(),X_MR(800);Z_UP();
X_MR(400);
Y_DWN();
//19行目
X_ML(450);
Z_DWN(),X_ML(800);Z_UP();
X_ML(800);
Y_DWN();
//20行目
X_MR(1950);
}
* 結果 [#g0d32be8]
** 「豆」 [#ia154883]
#ref(2016b/Member/ta.kashi/Mission1/Fig_007.JPG,80%,デザイン)
** 「車」 [#r55c21f1]
#ref(2016b/Member/ta.kashi/Mission1/Fig_008.JPG,80%,デザイン)
** 「写」 [#c65845b7]
#ref(2016b/Member/ta.kashi/Mission1/Fig_009.JPG,80%,デザイン)
走査線の間隔が広いのでわかりにくいが,以下のように「写」と描画されている.Y軸の間隔をもっと小さくすればよいが,そこまで細かい制御はできなかった.
#ref(2016b/Member/ta.kashi/Mission1/Fig_010.JPG,80%,デザイン)
* 感想と反省 [#s0168e40]
mindstormシリーズは,実は小学生の時に使ったことがあり,簡単な茶運び人形程度のものであれば作ったことがあった.しかしその際はGUIでコードの記述を行っていたのに対し,今回はCライクな言語で記述する必要があった.GUIに比べて動作が視覚的に確認しづらいという点では苦労したが,プログラミングに対する理解が深まった.
H/Wでは,特に動作毎の微妙な誤差に悩まされたが,それも部品の調整やS/Wの調整で減らすことができた.
ページ名: