[[2012b]] #contents *課題1 [#h3fbdd6c] 図のようなコースを各自で作成した上で、次のような動作をするロボットを作成せよ。 コースの詳細については授業中説明する。 -1人目 ++ スタート地点から出発し、スタート地点外のすぐ近くに置かれたピンポン玉をつかむ。 ++ ピンポン玉をつかんだら速やかにスタート地点の境界の黒線に戻り、そこから黒線に沿って動いてゴール地点を目指す。~ ただしT字路では、直進、右折、左折を正しく判断させること。また、曲線部中央の障害物に接触しないようにすること。 ++ ゴール地点に到達したら、ゴールエリア外からピンポン玉をゴールにシュートする。~ ただし、どうしてもエリア外からのシュートが難しい場合は、エリア内からシュートした後、エリアから出てもよい。 -2人目 ++上の動作でスタートとゴールを逆にして同様の動きをするプログラムを作成せよ。ロボット本体は共通のものを使うとする。 #ref(2012b/Mission/2012b-mission1.png,100%,課題1のコース) *・・・・・・・・・・・・・・・・・・・・・・・・作成者・・・・・・・・・・・・・・・・・・・・・・・・ [#h3fbdd6c] kuRo【くろ】::Twitterで「黒騎士」と名乗っているところから、この名前になった。~ RCX(旧式)シリーズのグループ 6 左側(R6)~ ちなみに長野県内の某私立高校[普通科]出身。~ プログラムは未知との遭遇でした。~ ・・・・・・・・・環境・・・・・・・・・・ プログラム環境 PC[1](メイン)~ handmadePC~ CPU Intel(R) Core(TM) i7-2600K CPU @ 3.40GHz~ M/B ASUSTeK Computer INC. P8Z68-V PRO GEN3~ メモリ 24576MB RAM~ GPU NVIDIA GeForce GTX 560 Ti~ OS Operating System: Windows 7 Professional 64-bit~ OS Debian GNU/Linux~ PC[2](サブ)~ Panasonic CF-S10(カスタムメイド)~ CPU Intel(R) Core(TM) i7-2620M CPU @ 2.70GHz~ メモリ 8192MB RAM~ OS Operating System: Windows 7 Professional 64-bit~ OS Debian GNU/Linux~ ロボット運用環境 試作運用~ 場所 基本的に10番教室、夕方以降なので蛍光灯の光がメイン。~ 電池 Panasonic アルカリ乾電池単3型 LR6XJ~ 備考 仲間がいた。そこにはみんなの笑顔とロボットがいた。~ 実践運用~ 場所 kuRo宅フローリング床のダイニング。カーテンを閉め切り、外光を遮断した状態で蛍光灯を点灯し運用。~ 電池 Panasonic エボルタ単3形 LR6EJ~ 備考 冷蔵庫の裏にピンポン球が迷いこんでちょっとした大惨事だった。 ▼RCXの事はほとんど呟かないが参考に▼ https://twitter.com/_black_night_ * 最終目標とロボット紹介 [#h3fbdd6c] 黒い線と白い下地の境界線にそって動くプログラムを作り、2か所あるT字路ではそれぞれ交差の無い方の端にそってライントレースを行うようにする。~ 店頭をしない程度で極限まで車体を小さくし、どのロボットにも見られないスピードのある上に小回りの可能なライントレースロボットになることを最終目標とする。 以下に挙げる図のように光センサーの位置を動かしながら進むようにする。~ タイヤの動きでスムーズな走行が行えるように、右左それぞれに動きながらも前進する力が生まれるようにタイヤの動きを工夫してある。~ 具体的には、図にあるようにカーブする時内輪になる側を後ろに引くようにし、外輪になるタイヤを前進させるようにする。~ この時に、前進するタイヤのパワーを仮に100とすると、後退させるタイヤのパワーを60にすることで、強力な揺れを回避できるだけでなく振動によるセンサのご認識を防ぐことが可能となる。 #ref(プレゼンテーション1.png); ↓↓↓今回作成したロボット↓↓↓ #ref(DCF00443.JPG); 想像しやすいように軽トラックの画像を参照する。(フリー素材) #ref(struck_free_photo.png); ロボット基部を軽トラックのような構造にし、荷台に当たる部分にRCX2.0を配置した。~ アームは、単純に上下動作を行うだけになっており、紙の影響でピンポン玉が移動しない限りは基本的に100%捕まえることが出来た。~ 駆動部分に関しては、下の写真を参考に、歯車で駆動で生まれる力の進行方向を90°変更することで、アームの上下の動きを作っている。~ アームの動きをもう少し遅くするのが当初の予定だったが、限界までパワーを下げても大した変化を感じなかったので組み込まなかった。~ #ref(DCF00447.JPG); ギアに関して↓ #ref(DCF00446.JPG); 写真の通り、ギアは用意されているものの中で一番大きなものを利用した。~ また、後輪はタイヤにして4輪走行でも、今回同様2輪にしてブロック一つで支える走行方法でも可能だが、電池の残量によって行動に変化が表れにくい2輪タイプを採用した。 球の確保は見た目通りアームでつかむだけの作業である。~ 球の発射は、アームを持ち上げて車体を使って押し出す動作で構成されている。 基本的にこの構造のロボットと、ライントレースのプログラムで運用が可能だった。~ 成功したのは25/32回。失敗の要因としては、センサーが突然コースアウトしてしまったり、ピンポン玉がゴールまで到達しなかったりなどであった。 工夫した点↓ #ref(DCF00449.JPG); ロボットを構成する上で、意外と厄介に感じるのがケーブルの位置である。特にモーターの上にごちゃごちゃとブロックが乗ってしまっている場合、それらのケーブルを車体の横から出すと、ギアに挟まれてしまったり、タイヤに当たって思うような運用へとつながらなくなる可能性がある。 そこで今回、私はロボットの中にいくつか空洞をつくり、ケーブルの通り道を作った。~ 写真の様に、モーターの上からRCXの側面につながる空洞、フロントのセンサーからRCXの側面につながる空洞、これらの空洞を上手に配置し運用することで、ケーブルへのダメージを減らすことにもつながり、これからも積極的に取り入れていきたいと思っている。 * 感想と反省 [#h3fbdd6c] 反省点としては、最後の発射のタイミングがコースや、ロボットの運用環境によって左右されやすいという点。~ 本来であれば白い線に到達したタイミングで発射する予定だったが、動かなくて泣きたくなったので、タイマーで発射することにした。そこまでの運用は自分でも少し驚いたくらいにはうまくできたのでかなりうれしいと思っている。 しかしまだまだ修行不足だと感じた。プログラムを書いていて、ここをこうしたいと思っても、それを実現するためのテクニックを知らなくてとてももどかしかった。~ テストプログラムとして何度も書いて実現可能な動きを蓄積していきたい。~ さらに、ロボットのほうも、最後の最後まで改良を繰り返した。次の課題では、基本的なロボットの部分の構成をもう少し精密に組んでいくことが出来るようにしたいと思っている。 今回実践した中で、ロボットが紙の折り目を超えたりしようとするときにコースから外れてしまったりしていたので、もう少し修正のうまくできるような緻密なプログラムを構成していきたいと思う。 *:::::::::::::::::::::::プログラム:::::::::::::::::::::::: [#h3fbdd6c] プログラムは、「球の確保」「ライントレース」「発射」の三要素で構成した。~ 定義(#define)に、実際に使われていないものがあるが、ここまでたどり着くまでの軌跡なので個人的感情から残した。 タイマーを用いて、黒い線の右側を読み取るか左側を読み取るかを変えている。~ 特にココといった限定はしていない。範囲的に変える場所を指定しているので、電池による変化もさほど感じない。~ 今回は8.0Vから9.8V間での運用をしたが、このRCXは8.7V以下の電圧において誤動作を起こしやすくなることが分かった。特筆すべきは光センサの読む値が著しく変化してしまう点。~ もともと、光量によるセンサーの誤作動を防ぐために我が家のカーテンを閉め切り、蛍光灯二本のみを点灯した状態で行っていたが、それにもかかわらず光センサーの値が予想外の値を吐き出したため誤作動が生じた。9.0V台ではありえない事象だった。~ また、電圧が8.2V以下になった時点で自重により前進するのが不可能になった。よって電池を交換した。 #define go OnFwd(OUT_AC); //前へ進む #define back OnRev(OUT_AC); //後ろへ下がる #define turn_left Off(OUT_A); OnFwd(OUT_C); Wait(50); Off(OUT_C); //90度左に曲がる #define turn_right Off(OUT_C); OnFwd(OUT_A); Wait(50); Off(OUT_A);//90度右に曲がる #define left SetPower(OUT_A, 2); SetPower(OUT_C, 3); OnRev(OUT_A); OnFwd(OUT_C);//黒い領域の左側を読みながらライントレース #define right SetPower(OUT_A, 3); SetPower(OUT_C, 2); OnFwd(OUT_A); Off(OUT_C);//黒い領域の右側を読みながらライントレース #define senkai_l OnFwd(OUT_C); Wait(100); Off(OUT_C);//90度旋回させる #define THRESHOLD 46 //黒い部分と白い部分の域値の数字を定義 #define STEP 1 //白と黒の境界をセンサが読むタイミング #define Catch OnFwd(OUT_B); Wait(50); Off(OUT_B);//ピンポンだまをキャッチする動作 #define parge OnRev(OUT_B); Wait(50); OnFwd(OUT_AC); Wait(30); Off(OUT_AC); OnRev(OUT_AC); Wait(20); Off(OUT_ABC);//シュートの動作 task main () { { OnRev(OUT_B); Wait(10); Catch;//ピンポン球をキャッチし、ラインとレースに入る前の段階までをここで完了。以下から左に沿ったライントレースを開始する。 SetSensor(SENSOR_1, SENSOR_LIGHT); ClearTimer(0);//タイマーをリセット while(FastTimer(0) <= 700)//最初の直角と交差点の間のどこか { if(SENSOR_1 < THRESHOLD)//センサーが黒にある場合、左右の境界線の左側を読みながら進む { left; } else { right; } Wait(STEP); } right; Wait(50);//コースのインクがにじんでいるので微調整 ClearTimer(1);// while(FastTimer(1) <= 1500 )//一個目の交差点の直前から次の交差点までの間の曲線間のどこかまでの時間。 { if(SENSOR_1 < THRESHOLD)//黒い線と白い線の右側の境界を読む { right; } else { left; } Wait(STEP); } ClearTimer(2); while(FastTimer(2) <= 1400 )//二個目の交差点の前の曲線からゴール手前の短い直線まで、黒い線の左側境界を読む。 { SetPower(OUT_AC, 2); if(SENSOR_1 < THRESHOLD) { left; } else { right; } Wait(STEP); } parge;//発射する。この時ゴール直前のコースの短い直線状にいる。 parge;//発射する。この時ゴール直前のコースの短い直線上にいる。 }