[[2018a/Member]] *ロボットについて [#d9728625] わたしたちは、機動性を重視したロボットを作った。ロボットの外見は次の写真のとおりである。 #refrobo.png この写真を見てわかる通り、ロボット作成の際に工夫した点が2つある。 第一に、光センサーの位置である。光センサーを中心より若干前方にずらすことで後で述べるライントレースにおいて効率的に動作できるようにした。また、地面に極限まで近づけることで小さな変化を読み取りやすくしている。 第二に、アームに関する部分である。試作品はすべてのモーターが平行に並んでいたため、急カーブに弱く、すぐに転倒していた。しかし、アームとなるモーターをタイヤとして利用したモーターの向きと垂直にすることで、NXT本体によって重心がやや後ろ向きにあった試作品の欠点をカバーすることができた。 *移動コース [#f85d89a7] 私の担当するコースは第1コースで、以下の写真のようなコースを移動するロボットを作成した。 #ref 写真では、線が色分けされているがここでプログラムが変化する部分と、わかりにくいかもしれないが、ライントレースにおいて、大きめにトレースするか、細かく移動するかを示している。 *サブルーチン [#o8e6dcb2] 今回のロボット製作で使用したサブルーチンは2つである。 +ライントレースをスムーズに早く行うサブルーチン 私はこのサブルーチンを「Line1」と定義した。これは、緩やかなカーブや、出発地点のような直線の道に対してすばやく移動することができるプログラムで、内容は次のとおりである。 sub Line1 () { int n = 0; if(SENSOR_1<50) { rt; n=0; } else if(SENSOR_1>50) { lt; n++; } } 2. 複雑な進路を慎重にライントレースするサブルーチン 私はこのサブルーチンを「Line2」と定義した。このサブルーチンは円部分の交差点や、ヘアピンカーブのような急カーブに対応できるプログラムで、内容は次のとおりである。 sub Line2 () { int n = 0; if(SENSOR_1<50) { rtt; n=0; } else if(SENSOR_1>50) { ltt; n++; } } *プログラムの工夫点 [#s60f7cbf] プログラムでは、交差点を境目として、大きく7つの動作に分かれている。 プログラムの内容は次のとおりである。 #define rt OnRev(OUT_C,40);OnRev(OUT_B,15);Wait(100); #define lt OnRev(OUT_B,40);OnRev(OUT_C,15);Wait(100); #define rtt OnRev(OUT_C,30);OnFwd(OUT_B,10);Wait(100); #define ltt OnRev(OUT_B,30);OnFwd(OUT_C,10);Wait(100); sub Line1 () { int n = 0; if(SENSOR_1<50) { rt; n=0; } else if(SENSOR_1>50) { lt; n++; } } sub Line2 () { int n = 0; if(SENSOR_1<50) { rtt; n=0; } else if(SENSOR_1>50) { ltt; n++; } } task main() { int n = 0; //交差点を認識させるための数字の定義 SetSensorLight(S1); int i = 0; //交差点動作後の行動を変化させるための数字の定義 while(i < 1) { Line1(); if( n > 5) //0.5秒以上黒を認識したとき { PlaySound (SOUND_CLICK); Wait(50); rt; until (SENSOR_1>50); Off(OUT_BC); Wait(1500); OnRev(OUT_BC,30); Wait(300); lt; until (SENSOR_1<50); i++; } } while(i < 2) { Line2(); if(n> 5) { PlaySound (SOUND_CLICK); Wait(50); Off(OUT_BC); Wait(1500); OnFwd(OUT_A,60); //カンを掴むためのアームを下ろす Wait(700); lt; until (SENSOR_1<50); //ライントレースできる地点まで移動する i++; } } while(i < 3) { Line2(); if(n> 5) //0.5秒以上黒を認識したとき { PlaySound (SOUND_CLICK); Wait(50); Off(OUT_BC); Wait(1500); OnRev(OUT_BC,30); Wait(500); rt; until (SENSOR_1>50); //ライントレースで地点ところまで移動する i++; } } while(i < 4) { Line2(); if(n> 5) //0.5秒以上黒を認識したとき { PlaySound (SOUND_CLICK); Wait(50); Off(OUT_BC); Wait(1500); OnRev(OUT_BC,30); Wait(500); rt; Wait(350); Off(OUT_BC); Wait(100); rt; until (SENSOR_1>50); //ライントレースできる地点まで移動する i++; } } while(i < 5) { Line2(); if(n> 5) //0.5秒以上黒を認識したとき { PlaySound (SOUND_CLICK); Wait(50); Off(OUT_BC); Wait(1500); OnRev(OUT_A,60); Wait(700); lt; until (SENSOR_1<50); //ライントレースできる地点まで移動する i++; } } while(i < 6) { Line1(); if( n > 5) //0.5秒以上黒を認識したとき { PlaySound (SOUND_CLICK); Wait(50); lt; Wait(350); Off(OUT_BC); Wait(1500); OnRev(OUT_BC,30); Wait(300); rt; until (SENSOR_1<50); //ライントレースできる地点まで移動する i++; } } while(i < 7) { Line1(); if( n > 5) //0.5秒以上黒を認識したとき { PlaySound (SOUND_CLICK); Wait(50); rt; Wait(150); Off(OUT_BC); Wait(1500); OnRev(OUT_BC,30); Wait(300); PlaySound (SOUND_CLICK); Wait(150); Off(OUT_BC); } } } 私は、主にwhileのコマンドを使ってプログラムを行った。写真の線をコース順に番号わけすると、最初に int i=0 を設定し、while (i<1)のように、設定した数字以下で動くようにプログラミングして、交差点や、動きを変えたいタイミングを if コマンドで条件をつけたあと i++ で次のプログラムへと移り変わることができるようにプログラムした。 *今回の課題における苦労した点と反省点 [#x362eee4] 今回の課題において私が苦労したことは、交差点の認識である。理由としては、最初に Current Tick を利用して時間を計測することで交差点を認識するプログラムを作ろうとしていたが、何度やってもうまく行かず、現在のような形式で認識するようにしたため、他のメンバーよりも大きく出遅れてしまったことで、時間との戦いとなってしまったことにある。反省点の一つであるが、そのように1つのパターンに固執してしまったことで、プログラムを柔軟に行うことができなかったと思う。また、反省点として今回は大きく分けて7つのプログラムに分かれているが、この7つをサブルーチンで定義することで、メインルーチンをかなり簡潔にすることができたと思う。