- 追加された行はこの色です。
- 削除された行はこの色です。
[[2019a/Member]]
#contents
*課題 [#xb13a38e]
詳しくは2019年度前期 課題2を参照~
#ref(2019a/Member/Hinata/Mission2/2019a-mission2.png,100%,a)
私は以下のコースを走る~
・A地点から出発 → M → K(直進) → L(ピンポン玉をつかむ) → K(右折) → J(一時停止の後、左折) → I(直進) → H(直進) → G(左折) → F → E → D(一時停止の後、直進) → C(直進) → B(一時停止) → シュート→ A地点に入る(ゴール)
*ロボットについて [#ye6c477a]
#ref(2019a/Member/Hinata/Mission2/
写真の撮り忘れ~
ロボットはNXTを使用している。~
バッテリーの上に載っているモーターにより枠が動く機構を搭載した~
基本のロボットにアームを取り付けられるようにわずかに改造している。ボールが非常に軽かったので枠に入れて転がすだけの構造が重量の観点からも良いものとなった~
*プログラム [#fcd1ec0a]
**基本事項 [#b7c19ed8]
細かい制御のために黒線の右側をトレースするものと左側をトレースするプログラムをそれぞれ書き、その2つを適宜交換させて稼働させた~
またライントレースの際に直線で走る明るさの基準は45とした
**定義 [#u5eb353b]
***アームについて [#gb048f4f]
#ref(2019a/Member/Hinata/Mission2
単純に枠の上げ下げのみにつかわれる~
センサーのケーブルがこのアームに干渉しないように、かつ移動の邪魔にならないような位置はこの辺りがベストだと考えた。重心ができるだけ車軸の上に来るようにする~
アームは単純な上下運動のみだ
#define arm_down OnFwd(OUT_C,15);Wait(1000); //アームの上下動作
#define arm_up OnRev(OUT_C,15);Wait(1000);
#define arm_down OnFwd(OUT_A,15);Wait(1000); //アームの上下動作
#define arm_up OnRev(OUT_A,15);Wait(1000);
***基本骨子 [#a32ed531]
#define Baced 45 //中間となる明るさの定義
#define speed 20
#define SPEED 30
#define OnRL(speedR,speedL) OnFwd(OUT_B,speedR);OnFwd(OUT_C,speedL);//簡略化のための定義
ここではマクロをさらに見やすくするための定義が書かれている。これが無いと全体がもっさりとしたものになる
***移動に使用するマクロ [#x3fbb24f]
#define Deep_turn_R OnRL(-speed,speed); //Deepで両車輪を回し、深く曲がる
#define turn_R OnRL(0,speed); //片方の車輪のみを動かす
#define Straight OnRL(speed,speed); //直進
#define Deep_turn_L OnRL(speed,-speed);
#define turn_L OnRL(speed,0);
#define turning_R OnRL(-SPEED,SPEED);Wait(500); //時計回りに90度回転
#define turning_L OnRL(SPEED,-SPEED);Wait(500); //反時計回りに90度回転
#define cross_line OnFwd(OUT_BC,15);Wait(300); //交差点をを横切る
#define turning_R OnRL(-speed,speeed);Wait(500); //時計回りに90度回転
#define turning_L OnRL(speed,-speed);Wait(500); //反時計回りに90度回転
#define cross_line OnFwd(OUT_BC,15);Wait(300); //交差点を横切る
ここまでがライントレースに用いるマクロ。後述のサブルーチンに頻繁に登場する
出来るだけ見やすく表記することに努めた。
***その他の行動 [#v2983288]
#define turn_line OnRL(SPEED,-SPEED);Wait(1000) //ボールをつかんで反転するときに使用
#define tea_time Off(OUT_BC);Wait(1000); //一時停止 別にお茶は飲まない
#define kick OnRL(speed,speed);Wait(700); //最後のシュートに使用 キックはしない
**サブルーチン関数 [#q923bfc4]
#ref(2019a/Member/Hinata/Mission2/無題あ.png,100%,bb)
これはライントレースのイメージ画像
#ref(2019a/Member/Hinata/Mission2/aaaa.jpg,100%,aaaa)
主に使用する右側、左側のライントレースが一つずつ。ボールを捕獲する道なりで使用する専用の左側トレースをひとつ。計三つのサブループチンを活用した。
***右側のトレース [#l6a68ec9]
sub R_trace(int Z){ //道の右側をトレースして交差点で停止する
SetSensorLight(S1);
long t0;
t0=CurrentTick(); //タイマーをセット
while (CurrentTick()-t0<Z) { //Z秒以上深く右に曲がるまで永続
if (SENSOR_1 < Baced-10) { //基準の明るさからー10の時の動作(黒線の上)
Deep_turn_R;
}
else if (SENSOR_1 < Baced-5) {turn_R;//基準の明るさからー5のとき(やや黒線より)
t0=CurrentTick();}
else if (SENSOR_1 < Baced+5) {Straight; //いい感じの位置
t0=CurrentTick();}
else if (SENSOR_1 < Baced+10) {turn_L; //黒線からやや離れている
t0=CurrentTick();}
else {Deep_turn_L; //黒線から完全に離れている
t0=CurrentTick();}
}
turning_L; //左に旋回
cross_line; //直進して交差点を渡る
}
右側をトレースして交差点をわたるサブ関数~
Zの時間以上右に曲がれば交差点と判断するようになっている。~
コースのL〜K、F〜B間で使用。黄緑色の部分で作動する
***左側のトレース1 [#a2cabf16]
sub L_trace_A(int X){ //上記のR_traceの左バージョン
SetSensorLight(S1);
long t0;
t0=CurrentTick();
while (CurrentTick()-t0<X) {
if (SENSOR_1 < Baced-10) {
Deep_turn_L;
}
else if (SENSOR_1 < Baced-5) {turn_L;
t0=CurrentTick();}
else if (SENSOR_1 < Baced+5) {Straight;
t0=CurrentTick();}
else if (SENSOR_1 < Baced+10) {turn_R;
t0=CurrentTick();}
else {Deep_turn_R;
t0=CurrentTick();}
}
turning_R; //右旋回
cross_line; //交差点の横断
}
こちらはR_traceと違い左側をトレースしながら移動するようになっている~
左に曲がり続けると交差点と判断される~
コースのM〜K、J〜Gで使用。基本の左側トレース。紫色の区間
***左側トレース2 [#e0804cf8]
sub L_trace_B(int Y){ //左側トレース第二弾
SetSensorLight(S1);
long t0;
t0=CurrentTick();
while (CurrentTick()-t0<Y) {
if (SENSOR_1 < Baced-10) {Deep_turn_R;
t0=CurrentTick();}
else if (SENSOR_1 < Baced-5) {turn_L;
t0=CurrentTick();}
else if (SENSOR_1 < Baced+5) {Straight;
t0=CurrentTick();}
else if (SENSOR_1 < Baced+10) {turn_R;
t0=CurrentTick();}
else {Deep_turn_R; //右に曲がり続けたときに止まるようになっている
}
}
turning_L; //左旋回
}
こちらは先の交差点を渡るものと違いK〜L間でのみ使用される、コースの先が無いときに用いるサブ関数となっている~
時間Yの調整により使用に至る。オレンジ色の区間で動作する~
黒線から外れた時に停止する
**メインタスク [#ia72e381]
task main(){
L_trace_A(320); //左側トレースから開始
L_trace_B(280);
arm_down; //アームをさげてボールをキャッチ
turn_line;
R_trace(320); //右側トレース区間
L_trace_A(220); //KからJへ
tea_time; //一時停止
L_trace_A(270);
L_trace_A(270);
L_trace_A(270); //Gへ到達
R_trace(320); //右側のトレース
tea_time; //一時停止
R_trace(320); //D〜B区間
tea_time; //一時停止
arm_up;
kick;
}
*まとめ [#pbb79780]
センサーに使った値がよかったのか道はかなりスムーズに進めた。急なカーブも難なく渡れる結果には満足している。~
交差点の識別からの立ち上がりが大味になってしまったが、スムーズな移動にかなり助けられた。~
**反省 [#g49f736c]
スムーズな移動ではあったが、時折ボールを上手くとらえることができなかった。~
これはロボット本体が大きく、それによって振れ幅も大きくなることが主な原因と考えられる~
更に足回りを小型に改良できれば精度も上がっただろう。
だが悲しいかな、私にそのような技量は備わっていなかった。~
本体のバランスとセンサーの位置が問題で、両方の安定を図ろうとすると期限内に完成しない可能性も多分にあり見送らざるを得なかった~