〜課題3〜 目次 #contents *課題 [#k9831262] ・半径1m以内にある空き缶を探して、25cmの距離からボールを転がしてその空き缶に当てるロボットを製作しなさい。ただし25cm以内に空き缶がある場合には、30cmまで離れること。 自分は、1のA地点からB地点へのルートを選択した。 *製作する上で工夫した点 [#ned7e2fc] **ロボット本体 [#zee4c438] ・ロボット本体にパーツを付けやすくするために、モーターを地面に水平にした。 ・本体前部にクワ型状のアーム1を取り付けた。 ・本体上部前方に、モーターを1つ取り付けてショベル型状のアーム2作った。 ・本体下部前方に光センサーを取り付けた。 ・本体についている個々のパーツ(アーム1、アーム2)は接合部が複雑でないので簡単に取り外して、片づけることが可能。 ・超音波センサーはショベル型のアームの上部に設置した。 #ref(./本体1.jpg,10%) #ref(./超音波センサー.jpg,10%) **アーム1(クワ型) [#x371323d] ・本体前部に、タイヤも含めた横幅と同じ長さのアームを取り付けた。縦の長さはボール2個分の長さと同じにして、やや余裕を持たせた。 ・水平に取り付けるとボールが下から通り抜けることがあるので、やや下に傾くようにした。 ・タイヤが付いている二つのモーターの間に感覚をもたせ、光センサーがちょうど取り付けられるようにした。アームは二つのモーターに直接取り付けた。 #ref(./アーム1.jpg,10%) #ref(./アーム2.jpg,10%) **アーム2(ショベル型) [#odd4f12c] ・本体上部前方のクワ型に入ったボールが出ないようにするために、ショベル型のアームを設置した。 ・アームの幅はクワガタの横幅と同じにして、ボールが出ないようにした。 ・アームは、スタート地点では上にあげていてボールが入るタイミングで下がるようにしている。 ・アームが下がりすぎて地面と接触しないように、ストッパーを設置した。 #ref(./ショベル1.jpg,10%) *プログラム [#c9146c3d] **定義の説明 [#t841a54b] #define SPEED 50・・・通常の移動スピード #define SPEED_SLOW 30・・・遅い移動スピード #define goal OnRev(OUT_BC,50);Wait(500);Off(OUT_BC);Wait(500);\ up;OnFwd(OUT_BC,100);Wait(300);Off(OUT_BC);・・・缶にボールを当てる up;OnFwd(OUT_BC,100);Wait(300);Off(OUT_BC);・・・缶にボールを当てる #define down OnFwd(OUT_A,40);Wait(500);Off(OUT_A);Wait(300);・・・ショベル型アームを下げる #define up OnRev(OUT_A,40);Wait(500);Off(OUT_A);Wait(300);・・・ショベル型アームを上げる **実際のプログラム [#zbefae11] #define SPEED 50 #define SPEED_SLOW 30 #define goal OnRev(OUT_BC,50);Wait(500);Off(OUT_BC);Wait(500);\ up;OnFwd(OUT_BC,100);Wait(300);Off(OUT_BC); #define down OnFwd(OUT_A,40);Wait(500);Off(OUT_A);Wait(300); #define up OnRev(OUT_A,40);Wait(500);Off(OUT_A);Wait(300); const float diameter = 5.45; //タイヤの直径 const float track = 10.35; //タイヤのトレッド幅 const float pi = 3.1415; //円周率 void fwdDist(float d) //距離 d cm前進 { long angle; angle = d/(diameter*pi)*360.0; //角度を計算する RotateMotorEx(OUT_BC,SPEED_SLOW,angle,0,true,true); } void turnAng(long ang) //角度ang度の時計周りの旋回 { long angle; angle = track/diameter * ang; RotateMotorEx(OUT_BC,SPEED_SLOW,angle,100,true,true); } int searchDirection(long ang) //現在の方向を中心にang度の範囲で探し障害物までの距離を返す { long angle,tacho_min=0,tacho_corr ; int d_min; d_min=300; //仮の最小値 angle = (track/diameter)*ang; //旋回角度からタイヤの回転を計算 turnAng(ang/2); //指定された角度の半分を旋回 ResetTachoCount(OUT_BC); //角度計測をリセット OnFwdSync(OUT_BC,SPEED_SLOW,-100); //反時計回りに旋回 while(MotorTachoCount(OUT_B)<=angle);{ if(SensorUS(S1)<d_min){ d_min=SensorUS(S1); //仮の最小値を更新 tacho_min=MotorTachoCount(OUT_B); } } OnFwdSyncEx(OUT_BC,SPEED_SLOW,100,RESET_NONE); until(MotorTachoCount(OUT_B)<=tacho_min||SensorUS(S1)<=d_min); Wait(14); //微調整 Off(OUT_BC);Wait(500); return d_min; } task main() { SetSensorLowspeed(S1); repeat(2){ //2回繰り返す int d = searchDirection(360); if (d > 10){ fwdDist(d-10.0); } } goal; } *作成した上での残った課題 [#o3eb7df6] ・プログラムは用紙の通りに打ち込めばよかったが、自分の理解が甘い個所があったので書かれているプログラムをちゃんと理解するのに時間がかかりすぎてしまった。 ・超音波センサーをショベル型のアームの上部に取り付けたが、頻繁に上の方に向いてしまうので、もう少し強固に取りつければよかった。 *感想と反省 [#j97622f4] ・プログラムを本体に入れて、実際に動かしてみたらNXTの超音波センサーの精度の高さに驚いた。 ・もう少し時間をかけて工夫出来ることがあったと思う。