2017b/Member

課題

ピンポン玉&紙コップ回収ロボット
22.0kb

ピンポン玉と紙コップを別々に回収してピンポン玉はX地点、紙コップはY地点に運ぶ。ルールやフィールドの詳細についてはこちらを参照してください。 http://yakushi.shinshu-u.ac.jp/robotics/?2017b%2FMission3

ルート説明

D点からC点まで直進した後左折する
C点からF点までライントレースする。
F点で交差点を認識した後左折する
超音波センサーが作動して紙コップを見つける。
“峭罎了罐灰奪廚鬚弔む
QS間の線を認識するまで後退。
X地点まで紙コップを運ぶ
紙コップを上げてピンポン玉を枠内に収める
ロボットをに番号の紙コップの方向に向ける
センサーを下ろしたあと、超音波センサーが作動して番号の紙コップを見つける
番号の紙コップをつかむ
QS間の線を認識するまで後退。
X地点まで紙コップを運ぶ
Y地点に紙コップを置く 

ロボットの本体説明

制作したロボットは一体で、コップを見つける、つかむ、重ねる、ピンポン玉を指定位置まで運ぶ動作、すべてを一体でこなせるようなロボットを製作した。

102.1kb

ロボット機構

コップを取るアーム

下方の腕はコップを固定して、上方の腕をモーターで動かすことでコップをつかむようにした。

102.1kb
超音波センサー

コップを見つけるセンサーはロボット前面中央、さらにセンサーを縦にしてつかうことで測定した紙コップまでの距離をより正確に測ることができるように工夫した。

63.4kb
光センサ―

下の画像のようにロボットの左右両方に光センサーを取り付け、光センサーを使い分けることで紙に描かれた線の読み取り方が増えた。その結果、複雑な動きをすることができるようになった

63.4kb

親機のコントロール部分

.蹈椒奪箸琉榮
超音波センサ―の動作
8センサーの動作

子機のコントロール部分

.灰奪廚鮗茲襯◆璽

コップをキャッチする順序

…恐伺肇札鵐機爾妊灰奪廚鮹気
▲灰奪廚鮓つけたら、超音波センサーを挙げる
ロボットは前に進んでコップをキャッチ
ぃのところに移動する
ゥ◆璽爐鬟▲奪廚靴謄團鵐櫂鷆未魏爾
δ恐伺肇札鵐機爾魏爾靴董⊆,離灰奪廚鮹気垢帽圓

コップを重ねる動作

コップを取るアームを下げて、固定したコップと重ねてからあげます

235.7kb

プログラミングの説明

課題3のプログラミングは2機のNXT間でBluetouthを介して通信を行うプログラムを使用しており、超音波センサーを用いて紙コップを認識した後、親機からの信号を受信し子機の紙コップをつかむプログラムが起動するプログラムである。

defineで次の内容を定義する。
#define SPEED 100     
#define SPEED_SLOW 60
#define turn_left1 OnFwd(OUT_A,80 * x); OnRev(OUT_C,35 * x); 左に回る
#define turn_left2 OnFwd(OUT_A,100 * x); OnFwd(OUT_C,40 * x);
#define turn_left3 OnFwd(OUT_A,80 * x); OnRev(OUT_C,90 * x);
#define turn_left5 OnFwd(OUT_A,80 * x); OnRev(OUT_C,1 * x);
#define go_forward OnFwd(OUT_A,80 * x); OnFwd(OUT_C,87 * x);
#define go_back OnRev(OUT_A,100 * x); OnRev(OUT_C,85 * x);
#define turn_right1 OnRev(OUT_A,35 * x); OnFwd(OUT_C,80 * x);
#define turn_right2 OnFwd(OUT_A,30 * x); OnFwd(OUT_C,100 * x);
#define turn_right3 OnRev(OUT_A,80 * x); OnFwd(OUT_C,80 * x);
#define AD SendRemoteNumber(1,MAILBOX1,01);       //アームを閉じて締める
#define AU SendRemoteNumber(1,MAILBOX1,02);       //アームを上げる
#define TD OnRev(OUT_B,45 * x); Wait(1000);
#define TU OnFwd(OUT_B,45 * x); Wait(1000);
#define CupOff SendRemoteNumber(1,MAILBOX1,03);   //コップを離す
#define turn_right4 OnRev(OUT_A,80 * x); OnFwd(OUT_C,60 * x);
#define turn_right5 OnRev(OUT_A,80 * x); OnFwd(OUT_C,1 * x);
#define turn_right6 OnRev(OUT_A,1 * x); OnFwd(OUT_C,80 * x);
#define DO  523
#define x 0.65             //かけ数
#define z 1.0

*サブルーチン 今回はサブルーチンとして「センサー2(光センサー)を使用して(左・右)に沿ってライントレースを行い、次の交差点に到着したら停止して音を鳴らす」「センサー3(光センサー)を使用して、左に沿ってライントレースを行い、次の交差点に到着したら停止して音を鳴らす」という3つのものを作成した。

右に沿ってライントレースするサブルーチン
sub IKK()        光センサ―
{
 int BP = 0;
 while (BP < 125){
 if (SENSOR_2 < 45) {
      turn_right1;
      BP++;
}else{
    if (SENSOR_2 < 49 ) {
     turn_right2;
   } else if (SENSOR_2 < 56 ) {
     go_forward;
   } else if (SENSOR_2 < 58) {
     turn_left2;
   } else {
     turn_left1;
   }
   BP = 0;
   }
  Wait(1);
  }
  Off(OUT_AC);
  PlayTone(DO,100); Wait(100);
  Wait(10);
  BP = 0;
}

左に沿ってライントレースするサブルーチン

sub DKK()
{
 int BP = 0;
 while (BP < 170){
 if (SENSOR_2 < 45) {
      turn_left1;
      BP++;
      }else{
    if (SENSOR_2 < 49 ) {
     turn_left2;
   } else if (SENSOR_2 < 54 ) {
     go_forward;
   } else if (SENSOR_2 < 55) {
     turn_right3;
   } else {
     turn_right4;
   }
   BP = 0;
   }
  Wait(1);
  }
  Off(OUT_AC);
  PlayTone(DO,100); Wait(100);
  BP = 0;
}

右側の光センサーを使い左に沿ってライントレースする

sub DKK2()
{
 int BP = 0;
 while (BP < 170){
 if (SENSOR_3 < 45) {
      turn_left1;
      BP++;
      }else{
    if (SENSOR_3 < 49 ) {
     turn_left2;
   } else if (SENSOR_3 < 54 ) {
     go_forward;
   } else if (SENSOR_3 < 55) {
     turn_right3;
   } else {
     turn_right4;
   }
   BP = 0;
   }
  Wait(1);
  }
  Off(OUT_AC);
  PlayTone(DO,100); Wait(100);
  BP = 0;
}

関数

そして今回は、紙コップを探し前進するプログラミングを関数として定義した。

const float diameter = 5.45;   //タイヤ直径
const float track = 10.35;    //タイヤトレッド幅
const float pi = 3.1415;     //円周率
void fwdDist(float d) //距離 dcm前進
{
long angle = d/(diameter*pi)*360.0;   //必要なタイヤの回転角度
RotateMotorEx(OUT_AC, SPEED_SLOW, angle, 0, true ,true);
}
void turnAng(long ang) //角度ang度の時計回りの旋回
{
long angle = track/diameter * ang;
RotateMotorEx(OUT_AC, SPEED_SLOW, angle, 100, true, true);
}
int searchDirection(long ang) //現在の方向を中心にang度の範囲で探し
                                  //障害物までの距離を返す
{
long tacho_min;  //最も近い距離を実現するタイヤの回転数
int d_min = 300;  //最も近い距離の仮の最小値(十分大きくとっておく)
long angle = (track/diameter)*ang;  //旋回角度からタイヤの回転を計算
turnAng(ang/2);   //指定された角度の半分を旋回
ResetTachoCount(OUT_AC);   //角度計測をリセット
OnFwdSync(OUT_AC,SPEED_SLOW,-100);  //半時計回りに旋回
while(MotorTachoCount(OUT_A)<=angle) {
if (SensorUS(S1)<d_min){ //現在の距離が借りの最小値より小さい場合
d_min = SensorUS(S1); //仮の最小値を更新
tacho_min = MotorTachoCount(OUT_A); //この時のタイヤの回転数を記録
}
}
OnFwdSyncEx(OUT_AC,SPEED_SLOW,100,RESET_NONE);
until(MotorTachoCount(OUT_A)<=tacho_min || SensorUS(S1)<=d_min);
Wait(14); //微調整
Off(OUT_AC);Wait(500);
return d_min;
}
task main()
{
SetSensorLowspeed(S1);
SetSensorLight(S2); 
SetSensorLight(S3);
go_forward;
Wait(500);  //少し前進
turn_left3;
Wait(200);
while (SENSOR_2 > 45)
{
turn_left3;  
}
turn_right1;
Wait(100);
IKK(); //Fまでライントレース
turn_left3;  
Wait(1000); //左向く 
int d = searchDirection(70);//コップ探す
if (d > 10){
fwdDist(d-10.0);//コップに近づく
} 
TU; //超音波センサーをあげる
go_forward;
Wait(2900);
AD; //コップを取る
Off(OUT_AC);
Wait(3000);
go_back;
Wait(500); 
turn_left3;
Wait(700); 
while (SENSOR_2 > 45)
{
go_back;  
}
go_back;
Wait(250);
Off(OUT_AC);
Wait(200);    
while (SENSOR_2 > 45)
{
go_back;  
} 
go_back;
Wait(450);
Off(OUT_AC);
Wait(450);  
while (SENSOR_2 > 45)
{
go_back;  
}
go_back;
Wait(250);
Off(OUT_AC);
Wait(200);
turn_right5; 
Wait(700);
while (SENSOR_3 > 45)
{
turn_right5;  
}
DKK2(); //Sを左折
//Qに到着
turn_right6;
Wait(1100);
while (SENSOR_2 > 45)
{
turn_right6;  
}
turn_right3;
Wait(300);
Off(OUT_AC);
Wait(1000);
go_forward;  //Xに入る
Wait(2500);
AU; //Xでコップを上げる
Off(OUT_AC);
Wait(3000);
go_back;
Wait(1200);
Off(OUT_AC);
Wait(2000);
while (SENSOR_2 > 45)
{
go_back;  
}
go_back;
Wait(500);
while (SENOSR_2 > 45)
{
go_back;  
}
Off(OUT_AC);
Wait(1000);
turn_right5;
Wait(500); 
while (SENSOR_3 > 45)
{
turn_right5;
}
turn_right5;
Wait(600);
while (SENSOR_3 > 45)
{
turn_right5;
}
Off(OUT_AC);
Wait(1000); 
go_forward;
Wait(1000);
while (SENSOR_2 > 45)
{
go_forward;
}
Off(OUT_AC);
Wait(1000);
while (SENSOR_3 > 45)
{
turn_left5;
}
turn_left5;
Wait(300);
go_forward;
Wait(500);
TD; //超音波下げる
Off(OUT_AC);
Wait(2000);
d = searchDirection(120);//コップ探す
if (d > 10){
fwdDist(d-10.0);//コップに近づく
}
TU; //超音波センサーをあげる
Off(OUT_AC);
Wait(1000);
go_forward;
Wait(1300); 
Off(OUT_AC);
Wait(1000); 
turn_left3;
Wait(1400);
Off(OUT_AC);
Wait(2000);
go_forward;
Wait(2300);
go_back;
Wait(100);
Off(OUT_AC);
Wait(500);
AD; //コップを取る(重ねる)
Off(OUT_AC);
Wait(3000);
go_back;     //kaiki
Wait(1900);
turn_right3;
Wait(1400);
go_back;
Wait(1300);
while (SENSOR_2 > 45)
{
go_back;  
}
turn_left5;
Wait(1200);
while (SENSOR_3 > 45)
{
turn_left5;  
}
turn_right5;
Wait(300);
go_forward;
Wait(1000);
while (SENSOR_2 > 45)
{
go_forward;  //Xまで直進
}
AU; //Xでコップを上げる
turn_left3;
Wait(200);
go_back;
Wait(300);
CupOff;
while (SENSOR_2 > 45)
{
go_back;  
}               //黒い線までバックする
turn_right3;
Wait(1000); //右折する
go_forward;
Wait(1000); //少し直進する
d = searchDirection(120); //コップ探す
if (d > 10){
fwdDist(d-10.0);//コップに近づく
}
TU; //超音波センサーをあげる
go_forward;
Wait(1000);
AD; //コップを取る
go_back;
Wait(1000);  //バックしてコースにもどる   
DKK();  //Bまでライントレースする
turn_left3; //左折する
Wait(1000);
DKK(); //Pに到着
turn_right3;
Wait(200);
go_forward;
Wait(1000); //Xにはいる
AU; //コップを上げる
go_back; 
Wait(1000); //Xから出る
turn_left3;   //左を向く
Wait(1000);
DKK(); //PからQまで円周上をライントレース
turn_left3;
Wait(1000);
DKK(); //Sに到着
turn_right3;
Wait(200);
go_forward; //Yに入る
Wait(1000);
AD; //コップを置く
CupOff; //コップ離す
}
*プログラミングの内容はパートナーが書いた内容を参考しました

URL:http://yakushi.shinshu-u.ac.jp/robotics/?2017b%2FMember%2Fwaitu%2FMission3

感想

1.ロボット全体の安定性はとても重要である。2.1位チームのロボットはすごい。

添付ファイル: file1.png 71件 [詳細] file24.jpg 66件 [詳細] file22.jpg 76件 [詳細] file21.jpg 61件 [詳細] file20.jpg 59件 [詳細] file19.jpg 69件 [詳細] file18.jpg 35件 [詳細] file16.jpg 30件 [詳細] file15.jpg 36件 [詳細] file14.jpg 32件 [詳細] file13.jpg 30件 [詳細] file11.jpg 44件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2018-02-13 (火) 21:09:12