[[2016a/Member]] #contents *はじめに [#t815dee9] 今回の課題は通常2〜3人であるチームが別チームと合体し5〜6人のチームでの活動となっています。 私のチームメンバーは、 「zawati」、「ngtrz」、「Ari」、「Etu」、「Tea」の5人チームです。 ([[2016年度前期 受講生のページ:http://yakushi.shinshu-u.ac.jp/robotics/?2016a%2FMember]]参照) **課題について [#e56365cb] [[課題2:http://yakushi.shinshu-u.ac.jp/robotics/?2016a%2FMission2]]で作成したコースを用いてタイムレースを行う。 **ルール [#pa880256] ***基本ルール [#l7b74867] ・紙コップをC地点、D地点にそれぞれ3個(合計6個)置き、C地点に置いた紙コップにはCを、D地点に置いた紙コップにはDを紙コップの底面にマークする ・紙コップは上下どちらにおいてもかまわない ・2台のロボットの場合はA地点とB地点からスタート、一体型の場合はA地点とB地点のいずれかからスタートする ・最終的に黒線で囲まれた輪の中にC地点からの紙コップとD地点からの紙コップを交互に重ねる (下側から数えて奇数番目はC地点からのコップ、偶数番目はD地点からのコップになるようにする) ・紙コップを重ねる場所は、必ずしも目的地点の輪の中でなくてもかまわない ・最終的に紙コップが自力で立っていること、またロボットが紙コップに触れていないこと、ただしスタート時と上下逆になっていてもかまわない ・競技時間はすべてのコップを重ね終わるまで、あるいは審判が続行不能と判断するまで。 ・審判の合図の後、5秒以内にロボットをスタートさせ、それ以降はロボットや紙コップに触ってはいけない ・紙コップに色を塗ったり文字や絵をかいてもよいが、穴を開けたり故意に変形させてはいけない ・光センサは2セット合わせて2つまで使って良い、その他のセンサや部品はキットに含まれているものだけを使用すること ***基本得点の計算方法 [#iff21f93] 1段目の紙コップ3点、2段目の紙コップ6点、・・、n段目のコップ3n点、6段目のコップ18点 奇数段目にあるDのコップと偶数段目にあるCのコップは0点 ***技術点の計算方法 [#cfca77c3] 以下の動作の精度・スピード・確実性などを含めた技術的な工夫や芸術性について他の全てのチームが20点満点で採点し、その平均点を求める。 得点の目安: スタートしてから紙コップの地点まで移動する速さ、正確さ (2点) 紙コップをつかむ動作 (3点) 紙コップをゴールまで運ぶ動作の速さ、正確さ (2点) 紙コップを重ねる動作 (3点) 2台のロボットの連携の良さ (3点) 自立型のロボットとしての形や動作の美しさ、斬新さ (3点) ロボコン出場ロボットとしての完成度 (2点) その他 (2点) ([[2016年度前期 課題3:http://yakushi.shinshu-u.ac.jp/robotics/?2016a%2FMission3]]引用、EV3関連事項については割愛させてもらいます) **作戦 [#y5ca8070] 私たちは、ロボット2台を別行動させることにしました。 1台は紙コップを自分たちが決めた場所へ運び(以下このロボットをスレーブ(従)と呼びます)、 もう1台は紙コップを持ち上げ決められた場所へ運びます(以下このロボットをマスター(主)と呼びます)。 具体的に述べると、 図1 #ref(2016a-mission3(1).png) スレーブ(S、赤線)はA地点から出発しC地点まで紙コップを取りに行きます。 その間マスター(M、緑線)はB地点から出発し☆のところで待機しています。 図2 #ref(2016a-mission3(2).png) そして、スレーブはC地点からP地点へと紙コップを運びマスターへ信号を送ります。 信号を受け取ったマスターは紙コップを持ち上げ、Q地点近くのサークルへ持っていきます。 図3 #ref(2016a-mission3(3).png) マスターが作業をしている間、スレーブはP地点から出発しD地点まで紙コップを取りに行きます。 マスターは作業終了後☆のところに戻り信号が送られてくるまで待機しています。 以下紙コップを運び、信号を送り、紙コップを持ち上げ運ぶの繰り返しです。 マスター担当は「zawati」、「ngtrz」、スレーブ担当は「Ari」、「Etu」、「Tea」となっています。 なお、ライントレースの有無は各担当で決めました。 *ロボットの説明―スレーブ側 [#pb1b9c01] #ref(robo5.jpg) 光センサを用いて、ライントレースをしながら進むようにしました。 また超音波センサを用いて、障害物(紙コップ)を認識したらアームを動かすようにしました。 アームの構造、その他細かい部分についてはスレーブ担当である3人([[Ari:http://yakushi.shinshu-u.ac.jp/robotics/?2016a%2FMember%2FAri%2FMission3]]、[[Etu:http://yakushi.shinshu-u.ac.jp/robotics/?2016a%2FMember%2FEtu%2FMission3]]、[[Tea:http://yakushi.shinshu-u.ac.jp/robotics/?2016a%2FMember%2FTea%2FMission3]])のページを参照してください。 *ロボットの説明―マスター側 [#qeed6834] #ref(robo6.jpg) こちらはライントレースをしませんでした。 紙コップを持ち上げているときにライントレースをすると、若干の振動により途中で紙コップを下ろしてしまったので無くしました。(詳しくは後述します) またこちらも超音波センサを用いて、障害物(紙コップ)を認識したらアームを動かすようにしました。 アームの構造、その他細かい部分についても後述します。 #ref(robo7.jpg) ちなみに、マスターがマスターだと分かるように、マスターには「マスターちゃん」を付けておきました。 (「マスターちゃん」という名前は私が勝手に付けました) **マスターアームの構造と経緯 [#y9c8180e] ***アームはどうするか [#l3a4b7f2] NXTのキットにはモーターが3つありますが、そのうち2つはタイヤに使われているため、使えるモーターは1つしかありませんでした。 私の頭の中では、 《紙コップをつかむのに1つ、持ち上げるのに1つは必要ではないだろうか? しかし、モーターは1つしかない・・・どうしたら・・・》 と、だいぶ悩みましたが結局いい案は出てこなく、過去の先輩のレポートを見ました。 すると、モーター1つでつかんで持ち上げているロボットが多々有り、正直驚きました。 その中からいくつか参考にさせてもらい、下の画像のようなアームができあがりました。 先輩方には感謝いたします。 ***つかむ仕組み [#b8192726] #ref(arm1.jpg) 苦労の末できあがりました「クワガタ型アーム」です。 真ん中の黒い棒は残っていたパーツの種類の都合上、どうしても無くせませんでした。 この時点では不必要なものと思っていましたがあとで役に立ちました。(後述) つかむ仕組みは以下の通りで、 #ref(arm2.jpg) 画像下部の垂直ギアを回すことで、2つの歯車間にあるウォームギアが回転します(緑)。 すると、その回転が両隣の歯車に伝わり(赤)、歯車とくっついているアームも動きます(青)。 垂直ギアを時計回りに回せばアームは開き、反時計回りに回せば閉じます。 ではこれで紙コップをつかんでみようと、実際に下のようにつかむと・・・少しぐらぐらするんです。 #ref(arm3.png) (丸いのは皿ではなく上から見た紙コップです。) ぐらぐらしていては安心もできません。困っていると同担当の「zawati」が見つけたのです。 「この黒い棒・・・使えないか?」 すると、 #ref(arm4.png) ぐらつきが無くなったのです。 2点よりも3点(赤点)のほうが安定感が増すのはこういうことだと改めて感じました。 これにより黒い棒は必要なものとなりました。 ***持ち上げる仕組み [#b35436b7] (絵がガタガタな件、黒い棒の太さが違う件、気にしないでください。私の実力不足です。) #ref(arm5.png) アームを模式的に表すと上のようになります。 垂直ギアを回すことで(緑)、アームは閉じていきます(青)。 #ref(arm6.png) アームを閉めていくと紙コップやアーム自身の締め付けが強くなります。 さらに締め付けを強くすればそれ相応の力が必要となります。 最終的に垂直ギアは動かなくなります。 #ref(arm7.png) 垂直ギアが動かなくなるのでアームには力が加わらなくなります。 しかし、動力を加え続ける限り垂直ギア自体に力が加わります。 これがアーム全体の重量(赤矢印)より大きくなると、アーム全体を動かす力が働きます。(青矢印は例) #ref(arm8.png) そこで、垂直ギアに垂直であるギアを用いて、垂直ギアを動かし、アーム全体を動かす力を上方向にかかるようにすると、 #ref(arm9.png) アームはその力の向きに沿って持ち上がります。 下げるときはモーターを反対方向にちょいと動かせば、アームの自重で下がります。 これにより、ライントレースをする際に若干の振動で下がってしまったのです。 ここはもう少し改良ができたのではないかと思いました。 それでも通常の進行であれば全く問題が無かったので、ここで持ち上げることに成功しました。 #ref(arm10.jpg) モーターに付けた感じが上の画像です。 ブロックなどを使って取り付けました。 また、アームの下に支えブロックを取り付けることによって、アームが上にのみ上がるようにしました。 **マスター超音波センサの取り付けと経緯 [#s8ac9d26] ***紙コップを認識するには [#i87fdb28] アームができた次は、紙コップをどうやって認識するかが問題でした。 最初タッチセンサを付けようという話になりましたが、あいにく付けれる場所が見つかりませんでした。 付けるならば、黒い棒の先端にですが、それだと3点が崩れるし、それに付けるだけでも多くのパーツが必要であったためやめました。 この時点で使えそうなパーツも少なくなっていたため、少ないパーツで何か認識できるセンサはないか探していると、 ありました。超音波センサです。 超音波センサを用いることで「○cm圏内に障害物あったらあれしろ」というのが可能になります。 なので、紙コップの認識には超音波センサを使うことにしました。 ***どこに付ける [#ac90f984] ではその超音波センサをどこに付けるか。 最初本体の上に付けましたが、アームを障害物認識してしまい紙コップをつかむことができませんでした。 次に本体の横に付けましたが、これもアームを障害物認識してしまいました。 ならばと思い、アーム下に付けると、見事アームを障害物認識しなくなりました。 試しに紙コップを置いてみると、きちんと認識しつかみました。 ここで紙コップの認識に成功しました。 (私は #ref(hontai.png) ↑これを「本体」と呼んでます。以下同様) ↑これを「本体」と呼んでます。) **結合 [#c0721dd7] #ref(robo8.jpg) 実際にアームと超音波センサを取り付けた様子が上の画像です。 アーム付モーターはタイヤ付モータ―の上に置き、タイヤ付モーターと結合しました(1カ所だけでも十分でした)。 超音波センサはアームの下に置き、アーム付モーター、タイヤ付モーターと結合しました。 これでロボットの準備は完了です。 *プログラム [#f8065fd3] **作戦との変更点 [#jcb8d9eb] プログラムを組んでいる中で作戦と変更しなければならないところが出てきました。 ・ライントレースをする都合上、スレーブは紙コップをP地点より数cmほど右に置くことになる →☆地点が18cm右へ移動(直線QRから右へ8cm移動) ・紙コップを置き、再び戻る際、その場でUターンする →マスターのアームとぶつかるので信号が送られてきても少しの時間待機 図4.変更点 #ref(2016a-mission3(4).png) 赤線、青線は後述のメインプログラムで使います。 **注意 [#s9d90515] スレーブプログラムについてはスレーブ担当である3人([[Ari:http://yakushi.shinshu-u.ac.jp/robotics/?2016a%2FMember%2FAri%2FMission3]]、[[Etu:http://yakushi.shinshu-u.ac.jp/robotics/?2016a%2FMember%2FEtu%2FMission3]]、[[Tea:http://yakushi.shinshu-u.ac.jp/robotics/?2016a%2FMember%2FTea%2FMission3]])のページを参照してください。 ここではマスタープログラムについて説明します。 **float型関数プログラム [#ked62cbb] 課題2([[2016a/Member/ngtrz/Mission2:http://yakushi.shinshu-u.ac.jp/robotics/?2016a%2FMember%2Fngtrz%2FMission2]]参照)同様、今回も進みたい距離からタイヤの回転角を計算するfloat型の関数を使ったプログラムを用いました。 float GetAngle(float d) /* dには進みたい距離が入る */ { const float diameter=5.45; //タイヤの直径(��) const float pi=3.1415; //円周率(π) float ang =d/(diameter*pi)*360.0; //角度を計算する return ang; //角度を返す } ***90°回転 [#cb5d1e80] 90°回転についても私の課題2のページで紹介しているのでそちらを参照してください。 90°回転の定義は以下の通りです。 #define Ninety GetAngle(8.25) ***&ruby(エル){l};cm進む [#u5e5d6d8] lcm進むについても私の課題2のページ(2cmとなっていますがlcmに直せば今回と同じくなります)で紹介しているのでそちらを参照してください。 lcm進むの定義は以下の通りです。 #define Rotary(l) GetAngle(l) // lcm分回転 **定義 [#z14a82fd] 先ほどの「90°回転」、「lcm進む」定義を元に「右旋回」、「左旋回」、「前進」、「後進」を定義しました。 #define Turn_r RotateMotorEx(OUT_BC,35,Ninety,100,true,false); //右旋回(モータBとCを35%のスピードで同期させず90度前転) #define Turn_l RotateMotorEx(OUT_BC,-35,Ninety,100,true,false); //左旋回(モータBとCを35%のスピードで同期させず90度後転) #define Go_F(l) RotateMotorEx(OUT_BC,25,Rotary(l),0,true,true); //lcm前進(モータBとCを25%のスピードで同期させてlcm分前転) #define Go_B(l) RotateMotorEx(OUT_BC,-25,Rotary(l),0,true,true); //lcm後進(モータBとCを25%のスピードで同期させてlcm分後転) また、アームの開閉に必要な定義をしました。 #define Tozire RotateMotor(OUT_A,50,800); //アームを閉じる(モータAを50%のスピードで800度前転) #define Hirake RotateMotor(OUT_A,-25,800); //アームを開く(モータAを25%のスピードで800度後転) ***アームの開閉定義問題 [#r02fb5f6] このアームの開閉定義にて問題が起こってしまいました。 「最初にアームをどの位置にしておいて、何度回転させればいいのか」 モーターの回転に過不足があってはいけないのです。 不足していれば紙コップを持ち上げることは無く、逆に過剰でも途中で止まってしまうのです。 (800°回転させて初めて次のプログラムへいくのだが、持ち上げすぎるとアームがモーターの部品についてモーターがそれ以上回らなくなる →800°回転を達成しない→次のプログラムへ行けない) これの対処には2つ考えられます。 1.アームの最初の位置をわかりやすい位置に決めて、回転角度を微調整する 2.回転角度を決めて、アームの最初の位置を微調整する ただ、明らかに1の方が正確であることに間違いはありません。 しかし私たちはなにを考えていたのか2の方でやってしまったのです。 アームの位置を微調整したってその位置を覚えていられるはずがないのに・・・ この選択がロボコンでの失敗につながることを、プログラムを組んでいる時の私たちはまだ知らなかったのです。 **紙コップ運搬サブルーチン [#a2db4042] sub Papercop() //紙コップを認識→持ち上げる→運ぶ→下ろす動作のサブルーチン { SetSensorLowspeed(S1); int n=0; //紙コップを認識した回数 while(n<1){ if (SensorUS(S1)<=10){ //紙コップとの距離が10cm以内なら Go_F(5); //紙コップを取りに行く Tozire; Turn_r; OnRev(OUT_B,50); Wait(100); //サークルまで直進できるよう調節 Go_F(10); //サークルに向かう Hirake; Go_B(10);☆地点に戻る OnRev(OUT_C,50); Wait(200); //P地点まで直進できるよう調節 Turn_l; OnFwd(OUT_B,50); Wait(100); Off(OUT_B); //P地点まで直進できるよう調節 Go_B(5); //スレーブが置いた紙コップにぶつからないようにするために下がる n++; //認識回数を増やす Off(OUT_BC); //待機 }else{ OnFwd(OUT_BC,50); //紙コップを探す } } n=0; //回数リセット } **メインプログラム [#p4999229] スレーブと通信するにあたり、以下を定義しました。 #define CONN 1 //スレーブの接続番号 #define Boot 11 //「紙コップを取りに来てください、マスター」メッセージ (「Boot」は「起動」という意味。マスターを起動させるという意から「Boot」と名付けました) 以下がメインプログラムです。 task main() { Go_F(25); //R地点まで進む Turn_r; //R地点右旋回 OnFwd(OUT_C,50); Wait(100); Off(OUT_C); //線(赤)に沿って進めるよう調節 Go_F(15); OnRev(OUT_C,50); Wait(100); Off(OUT_C); //Pと☆を結ぶ線(青)を直進できるよう調節 Turn_l; Off(OUT_BC); OnFwd(OUT_B,50); Wait(100); Off(OUT_B); //Pと☆を結ぶ線(青)を直進できるよう調節 Go_B(8); //☆地点まで後進 Off(OUT_BC); //待機 int x=0; //メッセージが送られてきた回数 while(x<6){ //紙コップは6個あるため6回繰り返す int msg; //受け取った値を格納する変数 ReceiveRemoteNumber(MAILBOX1,true,msg); //MAILBOX1の値を受け取りmsgに格納 //trueを指定するとメールボックスが空に if(msg == Boot){ //もしメッセージが送られてきたら Wait(1000); //スレーブとぶつからないように待機して Papercop(); x++; //メッセージが送られてきた回数を増やす }else{ Off(OUT_BC); //送られてこない限りは待機 } } } *ロボコン結果 [#c8f2c065] ロボコン開催1時間前。 私たちはリハーサルをすることにしました。 (実はこのとき初合わせ・・・これも反省点です。) そしてあの問題が起こってしまったのです。 「あれ、アームの最初の位置ってどこだっけ?」 このアームの最初の位置の微調整で30分は使ってしまったと思います。 また、スレーブ側にも問題が起こっていて、電源ONした後最初の1回はライントレースを必ず失敗してしまうそうです。 (2回目以降は成功していました) そんなこんなで数回あわせてやってみました。 すると、最後の方で2段の積み上げに成功しました。 チャンスも2回与えられ、1回目はライントレースができるか分からないけど2回目でいけると皆が確信していました。 そしてロボコンでの発表。 4段の積み上げを成功させることを目標に持ち(5,6段目の紙コップを取りに行くことができないと分かったため)、準備を始め、スタートしました。 予想通り1回目はライントレースの失敗。2回目に賭けました。 2回目はライントレース成功。紙コップも指定の位置に置くことができました。 しかし、持ち運びしているときにアームが少し動いてしまったのでしょう。 マスターは紙コップを持ち上げすぎて途中で止まってしまったのです。 そして私たちは紙コップを置くことすらできず終わってしまいました。 とても残念でした。 あのとき回転角度の微調整をしていれば・・・ もっと早くにマスターとスレーブを合わせることができれば・・・ いろいろと後悔しました。 しかし、技術点は高くつき、技術点において1位をとることができました。 *考察・感想 [#nc98ef6a] 上で述べた通り、私たちは紙コップを置くことすらできず終わってしまいました。 反省点も多くありました。 一番の後悔は早めに5人で集まってマスターとスレーブを合わせるべきだったことです。 試験週間でもあったため、作戦を伝える、助言を出し合うなどの簡単なことはしていたのですがそれだけでは足りなかったのでしょう。 いかに協調性が大事であるかを強く感じました。 このように悪いことが多かったのですが、悪いことだらけではありませんでした。 リハーサルで2段を積み上げることができたことは本当に感動しました。 教室に響き渡るんじゃないかというくらいの声を上げて喜び合いました(少し皆さんには失礼しましたが・・・)。 この感動は忘れられません。一人では絶対できなかったと思います。 仲間の大切さ、改めて強く感じました。 プログラムに関しては、今回もサブルーチンや定義を用いることによってコンパクトにできたのではないかと思います。 調整の部分でもう少しコンパクトにできるのではないかとも思いました。 *ロボティクス入門ゼミを通して [#dd1da42f] 実は私は化学系の人です。プログラミング系でも機械系でもありません。 ではなぜこのゼミをとったのか。ほんの少しだけロボットに興味があったからです。 プログラミングなどやったことがありませんでした。シラバスには、 「ウェブを閲覧する程度のパソコンの経験があることが望ましいが、プログラミングやホームページ作成の経験は必要ない。」 と書いてあったので、まあいけるだろうとこのゼミをとりました。 プログラミングについては先生の話を聞いたり、NXCの入門的ガイドを見たりして、簡単なものはできるようになりました。 しかし、やはり初心者。どんなにやっても失敗することが多かったです。 途中で挫折もしました。途中で逃げたくもなりました。 でもそんな私を支えてくれたのは仲間の存在でした。 仲間がいてくれたからこそ私はここまで来れたのではないか、そう思います。 何回も言いますが、仲間の大切さ、協調性の大切さ、強く実感しました。 コミュニケーション能力も少しは上達したと思います。 このロボティクス入門ゼミをとって本当によかったです。成長することができました。 *おまけ [#l5687249] ロボコンリハーサルにて動かしているときにですが、 実はスレーブとマスターの大きさはわりと差がありまして、スレーブが小さくマスターが大きく。 この2台が主従関係ではなく親子関係に見えてきました。 スレーブが(子供が)紙コップを取りに(おつかいに)行く。マスターが(父親が)紙コップを(帰ってくるのを)待つ。 ・・・ 父「紙コップを6つ買ってきてほしい。」 子「分かったよ!行ってきます!」 父(あの子1人で大丈夫だろうか・・・) 〜子、紙コップを買ってきたが手が小さく1つしか持ってこれなかった〜 子「ごめん・・・1つしか持ってこれなかった・・・」 父「大丈夫だ。ゆっくりでもいいから買ってきてほしい。」 子「じゃあ、また行ってくるね!」 父「行ってらっしゃい。」 〜父、紙コップを棚に入れる(サークルを棚に見立ててます)〜 子「2つ目持ってきた!また行ってくるね!」 ・・・ まるでおつかいのようでした。 見ていて和やかでしたね。 ロボコン1回目は子供が迷子になりました。 ロボコン2回目は父親が1個目を持ち上げた瞬間ぎっくり腰になりました。 こうしてとらえるのもいいのかもしれませんね。