- 追加された行はこの色です。
- 削除された行はこの色です。
[[2009a]]
目次
#contents
*ロボコン [#i216a021]
**課題:紙パック収集・分別ロボット [#eb002b4e]
***コースについて [#p24cd31c]
#ref(http://yakushi.shinshu-u.ac.jp/robotics/?plugin=attach&refer=2009a%2F%A5%ED%A5%DC%A5%B3%A5%F3&openfile=robocon2009a-1.png)
・紙パックを収集して色ごとに別の目的地まで運ぶ~
・フィールドは約160cm×110cm~
・運搬する500mlの紙パック(以下単に紙パックと呼ぶ)は約7cm×7cm×10.3cm~
・紙パックはすべての面に白あるいは緑色の画用紙がはられている~
・スタート地点の壁、中央の壁、ゴール近くの障害壁の断面は約89mm x 38mm~
・目的地の正方形の3辺は19mm×19mmの角材で仕切られている~
・黒い線の太さは約25mm~
***ルールについて [#e6fe077d]
・紙パックを所定の場所に運ぶ。~
・競技時間は審判が続行不能と判断するまで、あるいはリタイアするまでとする。~
・スタート時は上空も含め「スタート地点」からはみ出さないこと。~
・スタート時のロボットは2個を越えないこと (スタート後はいくつに分裂してもかまわない)。~
・開始の合図から5秒以内にRCXのスタートボタンを押す作業を完了すること。~
・競技が終了するまで、ロボットに触ったり人間が遠隔で操作してはならない。~
・途中でうまく動かなくなった場合、1回限り再スタートすることができる。~
・競技終了時点で、運んだ紙パックにロボットの一部が触れていてはならない。触れている場合は、その紙パックは加算しない。~
・ゴール内のフィールドに接地している紙パックだけを得点の対象とする。~
↑
**ロボットの説明 [#a2b770b0]
***ロボットA(ロボット運搬用):てつお [#a5f435d1]
***ロボットB(牛乳パック運搬用);ごんぞう [#hf15d427]
~ロボットBの移動は2つの光センサーによるライントレースで行った。
~ロボットAに載せて運搬するためになるべく全体が小さくまとまるように制作した。
~パックを掴む動作は4本のアームで左右からはさみこむように掴むものにした。
~パックをしっかりと保持するためにギヤにトルクギヤを使い常にパックに力がかかるようにした。
~ただし、パック同士の間隔が狭いのでアームが必要以上に開かない様にストッパーを付けた。
~また、ロボットが壁に近づきすぎるとパックを押し出してしまうのでタッチセンサーを少し前に出してロボットと壁の間隔を確保している。
**プログラム [#mdb7b4d9]
***てつお [#k450a430]
#define go_straight(t) OnRev(OUT_A+OUT_C);Wait(t);Off(OUT_A+OUT_C);
#define turn_right OnRev(OUT_A);OnFwd(OUT_C);Wait(150);Off(OUT_A+OUT_C);
#define turn_left OnRev(OUT_C);OnFwd(OUT_A);Wait(150);Off(OUT_C+OUT_A);
#define go_straight(t) OnFwd(OUT_A+OUT_C);Wait(t);Off(OUT_A+OUT_C);
#define turn_right OnFwd(OUT_A);OnRev(OUT_C);Wait(90);Off(OUT_A+OUT_C);
#define turn_left OnFwd(OUT_C);OnRev(OUT_A);Wait(90);Off(OUT_C+OUT_A);
#define SIGNALON 11
task main()
{
SetPower(OUT_A,7);
SetPower(OUT_C,7);
go_straight(80);
go_straight(110);
turn_right;
go_straight(80);
go_straight(110);
turn_right;
go_straight(80);
go_straight(110);
turn_left;
go_straight(80)
go_straight(100);
Off(OUT_A+OUT_B);
}
***ごんぞう [#l509c91a]
サブルーチンを多用して調整をしやすくし、
それぞれのパックごとにプログラムを組んである
時間指定とセンサーによる条件付けで多少の柔軟性を持たせた。
#define T_T81 //旋回時間1
#define T_T2 170 //旋回時間2
#define T_T81 //旋回時間1
#define T_T2 170 //旋回時間2
#define LINE 40
#define SIGNALON 11 //行動開始の信号
#define straight(t) OnFwd(OUT_B+OUT_C);Wait(t);Off(OUT_B+OUT_C);//直進のマクロ
以下はサブルーチン
sub turn_l() //左旋回1
{
OnFwd(OUT_C);OnRev(OUT_B);
Wait(T_T);
Off(OUT_B+OUT_C);
}
sub turn_r() //右旋回1
{
OnFwd(OUT_B);OnRev(OUT_C);
Wait(T_T);
Off(OUT_B+OUT_C);
}
sub turn2_l() //左旋回2
{
OnFwdOUT_C);Off(OUT_B);
Wait(T_T2);
Off(OUT_C);
}
sub turn2_r() //右旋回2
{
OnFwdOUT_B);Off(OUT_C);
Wait(T_T2);
Off(OUT_B);
}
sub catch() //パックを掴む動作
{
OnFwd(OUT_B+OUT_C); //タッチセンサーが反応するまで前進
until(SENSOR_3==1);
Off(OUT_B+OUT_C);
OnRev(OUT_A); //パックを掴む
Wait(60);
OnRev(OUT_B+OUT_C); //少し後退
Wait(50);
Off(OUT_B+OUT_C);
}
sub relese() //パックを放す
{
Off(OUT_B+OUT_C);
OnFwd(OUT_A);
Wait(60);
OnRev(OUT_B+OUT_C);
Wait(50);
Off(OUT_B+OUT_C);
}
メインプログラム
task main()
{
SetSensor(SENSOR_1,SENSOR_LIGHT); センサー1、2は光センサー
SetSensor(SENSOR_2,SENSOR_LIGHT);
SetSensor(SENSOR_3,SENSOR_TOUCH); センサー3はタッチセンサー
ClearTimer(0); タイマーリセット
ClearMessage(); メッセージクリア
until((Message()==SIGNALON)||(FastTimer(0)>1900)); 信号を受信または19秒経過
SendMessage(1); 返事を返す まで待機
until((Message()==SIGNALON)||(FastTimer(0)>1900));//信号を受信または19秒経過
SendMessage(1); // 返事を返す まで待機
OnFwd(OUT_B+OUT_C); ロボットAから降りる
OnFwd(OUT_B+OUT_C); //ロボットAから降りる
Wait(130);
OnFwd(OUT_A);
Wait(50);
Off(OUT_A+OUT_B+OUT_C);
Wait(150);
OnRev(OUT_B+OUT_C);
until((SENSOR_1<LINE)&&(SENSOR_2<LINE)); ラインを探す
until((SENSOR_1<LINE)&&(SENSOR_2<LINE)); //ラインを探す
OnFwd(OUT_C);Off(OUT_B);
Wait(150);
start folloW_line;
until(SENSOR_3==1); タッチセンサーが反応するまでライントレース
until(SENSOR_3==1); //タッチセンサーが反応するまでライントレース
stop follow_line;
Off(OUT_B+OUT_C); 停止
Off(OUT_B+OUT_C); //停止
Wait(30);
turn_l(); 左旋回
OnRev(OUT_B+OUT_C); 位置を調整
turn_l(); //左旋回
OnRev(OUT_B+OUT_C); //位置を調整
Wait(30);
Off(OUT_B+OUT_C);
catch(); パックを掴む
turn_l(); 左旋回
start follow_line; 光センサーが十字路を見つけるまでトレース
catch(); //パックを掴む
turn_l(); //左旋回
start follow_line; //光センサーが十字路を見つけるまでトレース
until((SENSOR_1<LINE)&&(SENSOR_2<LINE));
stop follow_line;
turn2_l; 光センサー2がラインに反応するまで右旋回
turn2_l; //光センサー2がラインに反応するまで右旋回
until(SENSOR_2<LINE);
start follow_line; 2.1秒間ライントレース
start follow_line; //2.1秒間ライントレース
Wait(210);
stop follow_line;
relese(); パックを放す
OnFwd(OUT_C);OnRev(OUT_B); 反転
relese(); //パックを放す
OnFwd(OUT_C);OnRev(OUT_B); //反転
Wait(170);
start follow_line; タッチセンサーが反応するまでトレース
start follow_line; //タッチセンサーが反応するまでトレース
until(SENSOR_3==1);
stop follow_line;
catch(); パックを掴む
OnFwd(OUT_C);OnRev(OUT_B); 反転
catch(); //パックを掴む
OnFwd(OUT_C);OnRev(OUT_B); //反転
Wait(170);
start follow_line; 2.1秒間ライントレース
start follow_line; //2.1秒間ライントレース
Wait(210);
stop follow_line;
relese(); パックを放す
OnFwd(OUT_C);OnRev(OUT_B); 反転
relese(); //パックを放す
OnFwd(OUT_C);OnRev(OUT_B); //反転
Wait(170);
start follow_line; 十字路までトレース
start follow_line; //十字路までトレース
until((SENSOR_1<LINE)&&(SENSOR_2<LINE));
stop follow_line;
turn2_r; 光センサー1が右旋回
turn2_r; //光センサー1が右旋回
until(SENSOR_1<LINE);
straight(50); 0.5秒間直進
turn_l; 左旋回
catch(); パックを掴む
straight(50); //0.5秒間直進
turn_l; //左旋回
catch(); //パックを掴む
turn_l();
start follow_line; 十字路までトレース
start follow_line; //十字路までトレース
Wait(100);
until((SENSOR_1<LINE)&&(SENSOR_2<LINE));
stop follow_line;
turn2_l(); センサー2が反応するまで左旋回
turn2_l(); //センサー2が反応するまで左旋回
until(SENSOR_2<LINE);
start follow_line; 2.1秒間直進
start follow_line; //2.1秒間直進
Wait(210);
stop follow_line;
relese(); パックを放す
OnFwd(OUT_C);OnRev(OUT_B); 反転
relese(); //パックを放す
OnFwd(OUT_C);OnRev(OUT_B); //反転
Wait(170);
start follow_line;
start follow_line; //タッチセンサーが反応するまでトレース
until(SENSOR_3==1);
stop follow_line;
catch();
OnFwd(OUT_C);OnRev(OUT_B);
catch(); //パックを掴む
OnFwd(OUT_C);OnRev(OUT_B); //反転
Wait(170);
start follow_line;
start follow_line; //2.1秒間ライントレース
Wait(210);
stop follow_line;
relese();
OnFwd(OUT_C);OnRev(OUT_B);
relese(); //パックを放す
OnFwd(OUT_C);OnRev(OUT_B); //反転
Wait(170);
start follow_line; 十字路までトレース
start follow_line; //十字路までトレース
until((SENSOR_1<LINE)&&(SENSOR_2<LINE));
stop follow_line;
turn2_l() 光センサー2が反応するまで左旋回
turn2_l() //光センサー2が反応するまで左旋回
until(SESOR_2<LINE);
start follow_line; タッチセンサーが反応するまでトレース
start follow_line; //タッチセンサーが反応するまでトレース
until(SENSOR_3==1);
stop follow_line;
turn_r(); 右旋回
OnRev(OUT_B+OUT_C); 位置を調整
turn_r(); //右旋回
OnRev(OUT_B+OUT_C); //位置を調整
Wait(30);
Off(OUT_B+OUT_C);
catch(); パックを掴む
turn_r(); 右旋回
start follow_line; 十字路までトレース
catch(); //パックを掴む
turn_r(); //右旋回
start follow_line; //十字路までトレース
until((SENSOR_1<LINE)&&(SENSOR_2<LINE));
stop follow_line;
turn2_r; 光センサー1が反応するまで右旋回
turn2_r; //光センサー1が反応するまで右旋回
until(SENSOR_1<LINE);
start follow_line; 2.1秒間トレース
start follow_line; //2.1秒間トレース
Wait(210);
stop follow_line;
relese(); パックを放す
OnFwd(OUT_B);OnRev(OUT_C); 反転
relese(); //パックを放す
OnFwd(OUT_B);OnRev(OUT_C); //反転
Wait(170);
start follow_line; 十字路までトレース
start follow_line; //十字路までトレース
until((SENSOR_1<LINE)&&(SENSOR_2<LINE));
stop follow_line;
turn2_l; 光センサー2が反応するまで左旋回
turn2_l; //光センサー2が反応するまで左旋回
until(SENSOR_2<LINE);
straight(50); 0.5秒間直進
turn_r; 右旋回
catch(); パックを掴む
turn_r(); 右旋回
start follow_line; 十字路までトレース
straight(50); //0.5秒間直進
turn_r; //右旋回
catch(); //パックを掴む
turn_r(); //右旋回
start follow_line; //十字路までトレース
Wait(120);
until((SENSOR_1<LINE)&&(SENSOR_2<LINE));
stop follow_line;
turn2_r(); 光センサー1が反応するまで右旋回
turn2_r(); //光センサー1が反応するまで右旋回
until(SENSOR_1<LINE);
start follow_line; 2.1秒間トレース
start follow_line; //2.1秒間トレース
Wait(210);
stop follow_line;
relese(); パックを放す
relese(); //パックを放す
}
task follow_line();{ ライントレースのタスク
task follow_line();{ //ライントレースのタスク
while(true){
if(SENSOR_1>LINE){ センサー1白
if(SENSOR_2<LINE){ センサー2黒のとき
OnFwd(OUT_B);Float(OUT_C); 右へ
if(SENSOR_1>LINE){ //センサー1白
if(SENSOR_2<LINE){ //センサー2黒のとき
OnFwd(OUT_B);Float(OUT_C); //右へ
}
else{ センサー2白のとき
OnFwd(OUT_B+OUT_C); 直進
else{ //センサー2白のとき
OnFwd(OUT_B+OUT_C); //直進
}
}
else{ センサー1黒
if(SENSOR_2>LINE){ センサー2白のとき
OnFwd(OUT_C);Float(OUT_B); 左へ
else{ //センサー1黒
if(SENSOR_2>LINE){ //センサー2白のとき
OnFwd(OUT_C);Float(OUT_B); //左へ
}
else{ センサー2黒のとき
OnFwd(OUT_B+OUT_C); 直進
else{ //センサー2黒のとき
OnFwd(OUT_B+OUT_C); //直進
}
}
}
}
**反省&感想 [#e7e2d3e9]
~ロボットBをコンパクトにまとめたつもりだったけど実際にはまだ大きかった様に思えた。また、プログラムについてはパックごとに分けたために非常に長くなってしまったのが反省点かと思う。(T.I)
**コメント欄(ご自由にどうぞ) [#x9573e05]
#comment