[[2016a/Member]]
#contents
*困惑の吐露のような愚痴の発散のような [#mfc00170]

 Ris一体、それに準じて光センサーも一つで課題をこなさなくてはならないことになっていた。何を言っているのかわからないだろうが私にもわからない。~
 時間かけた結果も散々だった。~
 久しぶりに吐いた。~
 その上で先生のまとめのお言葉を聞いた時「うわぁ先生その狙いでやってらっしゃったとはマジドンピシャで身にしみました先生そういうことだったんですね先生」ってなった。詳しくは後述。グダグダしてないと辛すぎて書けないんじゃ!!!!!!!!


08/23 20:40追記
&color(#e8383d){ルール読み間違えてたらしい。Ris一個でもセンサー2つ使ってよかったの事。};


*ハード [#g814f17e]

#ref(./DSC_0587.JPG,100)
 
 まず前述の通り~
 ・Ris一つ~
 ・=モーター3っつまで~
 ・=光センサー一つのみ~
で考える必要があった。なんでだよ。しらん。地面に巻いた水をすくえるかってんだ。しらん。~
その結果大前提として~
「ライントレースに光センサーを費やす以上、コップ回収には光センサーは使用不可」~
 またコードの調子が悪く、「タッチセンサーも使用が厳しい」という結論。つまり、「動きの正確さ及び確実性が必要」ということになった、なんてこったい。~
という前置きはここまでにして。~

 行動原理および作戦としては、~
「コップを横向きにひっくり返して重ねていく」「『運ぶ』のではなく『引きずっていく』」~
という発想である。コップ回収にセンサー利用が0である以上コップの初期位置に頼ることにした。要するに運。~
 だってコップ見つけるセンサー持てないんだもんね。~

**構造 [#g6a7fcf9]
***アーム [#j1093ab7]


#ref(./DSC_0591 - コピー.JPG,100)
 1.モーターから、一番小さいギア→一番大きいギアの順に伝達。これによって多少「馬力向上」と「回転速度低下」が実現される。~
 2.このタイヤと平行なモーターの回転運動をを棒の回転運動に変換する。理屈上はモーター自体タイヤと垂直でも良いはずだが、RIS上のコードの断線が怖すぎて回避。%%あと時間がなかったのと%%わかりやすさも優先された。(&color(#ea5550){※1};)~
 +α.この当たりは「補強(A)」や「先端の動作で必要(B)」な部分。(A)は丁度光センサー設置のブロックの穴にハマった上にはめると強度が上がったので活用。偶然の産物。(B)は後述(&color(#00947a){☆1};)。~

…そういえば光センサーの記述してない。~
 前回の課題にてこの位置にしたから、というわけだけでは実はなかった。数値変えればどうにでもなるし。まあライントレースうまく行くとわかっている位置としてかなりポイントは確かに高かったけども。~
 1つめに、前方であること。アームに比較的近いところであること。~
 2つめに、コップを引きずる上で邪魔にならないこと。~
 3つめに、正確なライントレースを求めるために、「あまり車体を振らないようにする=センサーが回転中心から遠すぎない」こと。(回転中心から遠いと、一瞬車体が曲がった時の円周が大きくなり、理想のグレーゾーンを超えて曲がりやすく、理想のグレーゾーンに留まりにくいことが課題2での結論。)

この点から、~

#ref(./DSC_0602 - コピー.JPG,100)


 設置点Aはバンパー(後述(&color(#00afcc){☆2};))の「わかりやすさ」を優先したことにより断念。(物理的に無理)~
 設置点Bはバンパーと紙コップの位置的な相性から「ここは空いている方が確実性があがる」という結論に至る。(たぶん後述(&color(#00afcc){☆2};))~
 そして設置点C。繰り返しの試行の結果「いうほどアームの影は影響してこない。走らせたらうまくライントレースしたから問題ない。」という結論に至る。~
 つまり、~
   作戦上のバンパーの有り方の形状>>>>>>>>>>>>>>バンパーの構造>>>>アームの影。~


#ref(./DSC_0593 - コピー (2).JPG,100)
#ref(./DSC_0594 - コピー.JPG,100)
 回転方向は図の通り。
 ここが先述(&color(#ea5550){※1};)によって親指上向きにした右ねじの方向へ回っていると歯車1は反時計回り、歯車2は時計回りに回転し、アームは閉じていく。このアームが閉じ切った(紙コップをつかむ/つかみ損ねてシュールにも閉じ切る)とき、この歯車1/2の回転は阻止され、動かなくなる。すると、このアームには右ねじの方向の回転力が依然加わるために、この回転軸を中心にしてアーム軸の反対側(右側)にアームがひっくり返る。この運動を十分な高さで、コップの初期状態を広い口を上向きに設置して行えば、アームの反対側(右側)に伏せた状態で詰まれていくことを狙っている。~
 逆にアームを初期状態に戻すとき、「コップが進むだけで入ってくれるように」アームを開いた状態にする必要がある。そのときはこの、(&color(#228b22){棒が伸びている部分};)が「アーム回転軸がこれ以上右ねじの反対方向に回転しない状態」を作り出し、それによってアーム回転軸の回転が歯車1/2に伝達するようになっている(完全に逆操作)。なおこの棒(=ストッパー)はアームが水平に開く状態を維持するのにも一役買っている。%%正味軽くて固定されていればなんでもよかったが%%軽さもコンパクトさも良好であり、アームの運動に阻害せず、かつ「アームが水平である」「アームを開く」のに欠かせない部分となった。さらにこれは(&color(#00947a){☆1};)の延長にあるものであり、固定のためのパーツ増量を活かした部分である。~
 なお、アームの軸回転が戻っている途中にアームが開きそうにも思うが、「完全に開いた状態を『確実に』つくる」にはこのワンクッション(?)がかなり確実性を上げる。~
 歯車2についている(&color(#0000cd){この部分};)は「アームが開ききった状態」を確定するもので、開きすぎて変なところで引っかかることを防ぎ、また、アームの閉じる時間をプログラミングした時に最大値が制限されるので安定しやすい等のメリットがある。~


***バンパー [#t013f3ce]
#ref(./DSC_0589.JPG,100)
(&color(#00afcc){☆2};)。~
 運ぶ(笑)ためのバンパー(仮称)である。バンパーの役割はない。むしろガードレール。~
 仕組みはGIFアニメにて。~

#ref(./1470985947CJd5B0L5T25RnU_1470985932.gif,50%)

#ref(./1470986068Dp1oyA0_F5g2zKR1470986060.gif,50%)


 なお、光センサーが真ん中の位置であると、以下のようになり、ライントレース程度の左折にも耐えられない可能性があったために光センサーはバンパー内に設置しなかった。~

#ref(./1470986829M1fPAhUxPPWah951470986824.gif,50%)



 本体は特にゴツさを極力削ったつもりである。~


**経緯 [#t6dd33d4]

 光センサーは先述したので省略。~
***アームの決定 [#kf43e754]
 まず、先生に教授いただいた方法を試してみた。女子二人で活動する、というのはつまり「いうほど幼少の頃そういうので遊んでないから知識がない」ことに直結していたので、「とりあえずやってみよう」という調子になるのはいたって自然である。と主張する。~
 教えていただいた機構は以下の通り。~

#ref(./名称未設定 1 - コピー.png,50)

 これについての考察として、~
・歯車の数が多い~
・ブロックで連結しなければならない→重たくなりそう~
・Ris一台分で動作させる必要がある →つまりアームの方が重くてバランスが持っていかれる~
                 →補強用ブロックも足りないのでは?~
・歯車とブロックの融合したごついモーターをRisの近くに設置できるのか~
というのは共通認識レベルで考えた。おそらくちゃんとそれらを解決できる方法があったのかもしれないが、その場では「応用的なアームを考えよう」という発想に至った。~


 重いアームが何故問題なのかを考えた時、それは「重いものを振ると重心が飛んでいくため安定しないからだ」と行きつき、~
・重くても、動かなければ重心は安定している~
・軽ければ、動いても重心は安定しやすい~
のどちらかにしようと意見をまとめた。~

 最初に考えたのは「エレベーター方式」である。おそらく「持ち上げる」という動作に対し連想するものにエレベーターは必ず関わる上に、初めに見た過去のロボコンの印象から浮かんだ発想だったと思う。しかし、~
・構造が複雑化=センサーなしでできると思えない+一台分では部品が足りない~
・紙コップは寸胴ではないので、両側からの押し上げ式の持ち上げは難しいのではないか~
・箱型(よくあるエレベーター)であれば「持ち上げる」動作と、ロボコンの規定上、「ロボットから離脱させる動作」が必要=モーターが一つ足らないのでは~
であるために断念。

本当に一台分でやらされたの糞だなあいつらどうさせようとしてたんだ当日手ぶらで来たし

 となれば、と「軽量化」に着手。~
 そこで浮かんだのが、「ブロックと歯車で回転運動を伝達する」のではなく、「棒一本での回転運動の伝達」である。~
 早速見本(歯車連結)と見比べながら試作。実際にモーターに接続するであろう向きまで考えて%%(あっモーターの向きこの時の名残かもしれない)%%いざ手で歯車を回してシミュレーション。~

 その結果が
#ref(./DSC_0611 - コピー - コピー.JPG,100)
こうである。~

 つまり想定していた動きと、得た動きはこのように差異があり、~
#ref(./DSC_0612 - コピー.JPG,100)
求めていた「タイヤと平行な向きの、上昇する回転運動」ではなく、「棒自体の回転運動」が永遠になされることが判明。確かに「棒の回転運動」を止める仕組みがないもんなァ…~
 棒の回転運動を止めるとアームの先端のつかむ動きもできないので、棒自体を固定する選択肢はない。~
 だが、なんというか、素晴らしい言い方をすれば「ひらめき」、しょうもない言い方と言えば「偶然の産物」ともいうもので、~
 これ、ある程度の高さがあったらこう…かぽって…お椀伏せる方式で…うん。~
#ref(./1470989773S6pCY4nj9uBCupQ1470989766.gif,50%)
という「理想の動きをしてくれなかったことによる%%やけくそ%%逆転の発想」が結果運用されることになった。~

***アーム先端 [#ge7ca0fb]
 使ったことのない部品を組み合わせながら「いかにして固定させるか」が課題となっていた。~
#ref(./DSC_0611 - コピー.JPG,100)~
 棒をできるだけ使い軽量化を狙う。~
 左側に伸びているのは(&color(#00947a){☆1};)のため。~
 アームの右側が直線的なのは「高さを下げないため」である。今回の作戦では回転させたときに高さが足りないと空振りをして終わってしまう。そのため、「高さ」は重要な要素であった。

<高さが足りないとどうなるか>~
#ref(./1470991212jEai3uFay5v6_oK1470991205.gif,50%)
<直線的でなかったらどうなるか>~
#ref(./14709912689blrdYdfnPwOt2_1470991264.gif,50%)

 また、直線的の方が紙コップが直進した時に入ってきやすいのではないか、との考えもあった。~
 ただ、同時にそれだと「つかむ」要素が薄れつかみ損ねかねないので、タイヤやひっそりとゴムを付けることでゴムの力で持ち上げることを考えた。~

#ref(./DSC_0603 - コピー.JPG,100)
***本体 [#tbcca449]
 アーム接地部分をブロックを敷き詰めることにより底上げ。(高さのため)(一層分)~
#ref(./DSC_0605 - コピー.JPG,100)~
 下への設置だけでなく、横向きへ伸ばした棒+ブロックで接地することにより、アームの棒自体の補強となった(一点支持から二点支持)。ちなみにこれは(&color(#00947a){☆1};)の一部。大活躍だね。~
#ref(./DSC_0607 - コピー - コピー.JPG)

***バンパー [#lb06882e]
 バンパーに求められたのは、~
・ライントレース程度の左折に耐える~
・コップをひっくり返すとき狙いのところにコップを都合のよいところに置く~
・最後コップが離脱する~
事である。~

#ref(./DSC_0606 - コピー.JPG,100)
#ref(./DSC_0608 - コピー.JPG,100)

 左折に耐えるためにAの部分は短すぎず、また、コップが離脱するためにBの空間を開けたかったためにAの部分は長すぎてもいけなかった。~
 Cの折れの位置はアームの長さに合わせ、アームが回転した時の着地点にコップが来るようになるようになっている。~


*大会時の狙っていた流れ [#y3ab3d56]

#ref(./1470998334O99JCPHqXwJ2zbl1470998333.gif,50%)
#ref(./1470998759K2PikBo2GqgReII1470998752.gif,50%)
#ref(./1470998901QBtGLZEWXKlCTqj1470998889.gif,50%)

「すでに獲得しているコップをバンパーの中で左上に寄せて」とは、
#ref(./1470986068Dp1oyA0_F5g2zKR1470986060.gif,50%)
の上方に寄せることである。



*大会時のプログラム [#ldd385a5]

  今見たら自分でも見にくくて震えてる…~
 「書き換えてみたプログラム」は運転してません(解体してしまった)。理論上は行けるはず…。~
 そうやって理論上に泣いてきたけどな!HAHAHA!!!!~

 控えめに言って汚すぎて説明できないです(おい)ミスしたところを指摘し修正添えます。それでたぶんゲームにはなります。~
 インライン関数を本質的に理解してないんですが、サブルーチン同様に使えるのであれば、もっときれいに描けた。サブルーチン8つの壁…。~
 ということで、サブルーチンとインライン関数が同じように使えると仮定し、少し書き直したものをつかって後ほど改めて説明しようと思います。間違いがあるかもしれませんがそっちの方が意図が分かりやすいと思います。
 しかしながら!!やはり!!!走らせてないプログラムだけ載せて「そもそも動きません」なんて致命的なミスがあったらやはり悲しいので大会のものも載せます。お時間あったら見比べていただけるとより意図が分かりやすいと(以下略)

**定義 [#i6399169]
前回同様のものが多い。

 #define straight 5
 #define carb 2   
 #define KAITEN 2  //大きいギアを一枚しか噛ませられなかったので、回転を極力遅くしたかった。
 #define set_straight SetPower(OUT_AC,straight);
 #define set_carb SetPower(OUT_AC,carb);
 #define set_kaiten SetPower(OUT_AC,KAITEN);
 #define arm_tsukamu(t) set_kaiten; OnFwd(OUT_B); Wait(t); Off(OUT_B);
 #define arm_hanasu(t) set_kaiten; OnRev(OUT_B); Wait(t); Off(OUT_B);
 #define go_forward set_straight; OnFwd(OUT_AC);
 #define turn_leftL set_carb; OnFwd(OUT_C); OnRev(OUT_A);
 #define turn_leftS set_carb; OnFwd(OUT_C); Off(OUT_A);
 #define turn_rightS set_carb; OnFwd(OUT_A); Off(OUT_C);
 #define turn_rightL set_carb; OnFwd(OUT_A); OnRev(OUT_C);
 #define black 38                  
 #define glayA 42
 #define glayB 45
 #define glayC 48
 #define white 50 
 #define KURO 11
 #define TURN_TIME 90
 #define TUKAMU_TIME 3
 #define HANASU_TIME 3
 #define MA_NO_ZIKAN 3
 #define ma_wo_toru Off(OUT_B); Wait(MA_NO_ZIKAN);


**サブルーチン [#t41a11a4]
 8個までなの本当に罠だよぉ!~


  sub go_go_left()//交差点で左折
  {
    Off(OUT_AC);
    Wait(100);
    PlaySound(SOUND_FAST_UP); 
    go_forward;
    Wait(50);
    turn_leftL;
    Wait(TURN_TIME);
    Off(OUT_AC);
    go_forward;
    Wait(50);
  }

  sub go_go_right()//交差点で右折
  {
    Off(OUT_AC);
    Wait(100);
    PlaySound(SOUND_FAST_UP); 
    turn_rightL;
    Wait(TURN_TIME);
    Off(OUT_AC);
  }

  sub go_go_forward()//交差点で直進
  {
    Off(OUT_AC);
    Wait(100);
    PlaySound(SOUND_FAST_UP); 
    go_forward;
    Wait(50);
    Off(OUT_AC);
  }

 交差点で左行って右行って直進する


  sub go_follow()//サブルーチン8個までということで無理やり統合。大恥の元。
   {
    ClearTimer(1); 
   while (FastTimer(1) <= 300) {   //タイマー1を使用
    if (SENSOR_2 < black) {        //黒の範囲にいるとき、
      turn_leftL;
    } else if (SENSOR_2 < glayA) { //黒寄りのところにいるとき、
      turn_leftS;                      //少し左に曲がりながら、
    } else if (SENSOR_2 < glayB) { //白寄りのところにいるとき、
      go_forward;                      //直進し、
    } else  {                      //それ以外のとき、つまり白いところにいるとき、 
      turn_rightL;                     //大きく右へいきながら、
    } 
    Wait(1);                       //この判定を0.01秒ごとにする
   }
    ClearTimer(0);
   while (FastTimer(0) <= KURO) {   //タイマー0を使用
    if (SENSOR_2 < black) {        //黒の範囲にいるとき、
      turn_leftL;
    } else if (SENSOR_2 < glayA) { //黒寄りのところにいるとき、
      turn_leftS;                      //少し左に曲がりながら、
       ClearTimer(0);                  //タイマーをリセットかける
    } else if (SENSOR_2 < glayB) { //白寄りのところにいるとき、
      go_forward;                      //直進し、
      ClearTimer(0);                   //タイマーをリセットする
    } else  {                      //それ以外のとき、つまり白いところにいるとき、 
      turn_rightL;                     //大きく右へいきながら、
      ClearTimer(0);                   //タイマーをリセットする。
    } 
    Wait(1);                       //この判定を0.01秒ごとにする
   }
  }

  sub tukamu()//コップをひっくり返す
  {
   repeat(6) {  //動く/とまるを瞬時に繰り返すことで、結果的に速度を落としたような動きを作る。
      arm_tsukamu(TUKAMU_TIME);
      ma_wo_toru;
     }
    OnRev(OUT_AC);//少し下がる(回転したりした時に他のコップに当たらないように。)
    Wait(80);
    Off(OUT_ABC);   
    turn_rightL;//アームの中でコップを狙いの位置へ誘導☆
    Wait(30);
    Off(OUT_AC);
   repeat(6) {  //※
       arm_tsukamu(TUKAMU_TIME);
       ma_wo_toru;
      }
     Off(OUT_B);//勢いが付きすぎると二個目以降はまだいいが、一個目が吹っ飛ぶ。
     Wait(5);//ここで一回勢いを殺すことで、一回目もちゃんと着地させる。
    repeat(3) {  //※
       arm_tsukamu(TUKAMU_TIME);
       ma_wo_toru;
      }
    }

 尚、全体的に速度/勢いを殺す動きをさせているが、勢いを殺し過ぎると二個目以降がコップにハマらなかったり浅いハマりで不安になることが多々。~
 ※のRepeatの数の比は重要。前の※が大きいとハメる予定のコップが勢い良すぎて吹っ飛び、後ろの※が大きいとハメ途中でハメられる予定のコップが逃げる。~

 ☆について
#ref(./1470986068Dp1oyA0_F5g2zKR1470986060.gif,50%)
 これの「上方に寄せる」ということ。これでコップが落ち着く地点にアームの長さが調整されている。


  sub hanasu()//離すというものの、実際はアームを元に戻す動き
    {
   repeat(22) {  //アームを開ききるために、アームを閉じるときより+6〜+8長くして確実性を高める 
     arm_hanasu(HANASU_TIME);
     ma_wo_toru;
    }
   }

  sub turn_180()//C/D地点でのターン用
   {
    turn_rightL;
    Wait(170);
    Off(OUT_AC);
    go_forward;
    Wait(50);
    Off(OUT_AC);
   }

**Task main [#x8a49667]
 task main ()
  {
   SetSensor(SENSOR_2,SENSOR_LIGHT);
    go_follow();//

&color(#e8383d){大失態。大恥};。交差点感知しなくて恥かいた。正しくは&color(#003f8e){交差点感知するライントレースを最初はぶち込む。これしかない。};統合したやつのサブルーチンしか用意してなかったのでまあ。うん。サブルーチンのみ使用の状況下ではあの長いのを突っ込むしかない。

    go_go_forward();
    go_follow();
    go_go_forward();
    go_follow();
    go_go_right();
    go_follow();//C到着
 
  int move_time;  // 整数型の変数を宣言
  move_time = 0;  

    go_forward;//C地点でコップがアームの中に入るようにすすむ(初回0)
    Wait(move_time);
    Off(OUT_AC);//
    tukamu();
    Off(OUT_B);
    Wait(100);
    hanasu();
    Off(OUT_B);
    Wait(100);//コップひっくり返し完(C一つ目)
    turn_180();
    go_follow();
    go_go_forward();
    go_follow();//D着
    turn_rightL;//
    Wait(50);//
  /*これ、書き直した方で言及してる(&color(#c70067){関連1};)ですわ。~
  最初自分でもなんだこれって思った。~
  Dでピタッと止まってくれないからこの段階を踏んで向きをラインと平行に正さないと,~
  コップにスッって入船する流れを作れなかったんだ…*/
    go_forward;
    Wait(move_time);
    Off(OUT_AC);//Dコップ圏内へ
    tukamu();
    Off(OUT_B);
    Wait(100);
    hanasu();
    Off(OUT_B);
    Wait(100);//コップひっくり返し完
    turn_180();
    go_follow();
    go_go_forward();
    go_follow();//C着

  move_time += 60;//コップをアームに入れるときにより進むことによって確実に入れに行くスタイル

    go_forward;
    Wait(move_time);
    Off(OUT_AC);//Cにてコップをアームにいれる
    tukamu();
    Off(OUT_B);
    Wait(100);
    hanasu();
    Off(OUT_B);
    Wait(100);//コップひっくり返し完
    OnRev(OUT_AC);
    Wait(move_time);
    turn_180();
    go_follow();
    go_go_forward();
    go_follow();//D着

    turn_rightL;
    Wait(50);
    go_forward;
    Wait(move_time);
    Off(OUT_AC);//Dコップ圏内4
    tukamu();
    Off(OUT_B);
    Wait(100);
    hanasu();
    Off(OUT_B);
    Wait(100);//コップひっくり返し完
    OnRev(OUT_AC);
    Wait(move_time);
    turn_180();
    go_follow();
    go_go_forward();
    go_follow();//C着

  move_time += 50;
  move_time += 50;//各スペース3つめ=3列目になるのでさらに奥のコップを取る

    go_forward;
    Wait(move_time);
    Off(OUT_AC);//Cコップ圏内5
    turn_rightS;
    Wait(30);
    Off(OUT_AC);
    tukamu();
    Off(OUT_B);
    Wait(100);
    hanasu();
    Off(OUT_B);
    Wait(100);//コップひっくり返し完
    OnRev(OUT_AC);
    Wait(move_time);
    turn_180();
    go_follow();
    go_go_forward();
    go_follow();//D着

    turn_rightL;
    Wait(50);
    go_forward;
    Wait(move_time);
    Off(OUT_AC);//Dコップ圏内6
    turn_rightS;
    Wait(30);
    Off(OUT_AC);
    tukamu();
    Off(OUT_B);
    Wait(100);
    hanasu();
    Off(OUT_B);
    Wait(100);//コップひっくり返しすべて完
    OnRev(OUT_AC);
    Wait(move_time);
    turn_180();
    go_follow();
    go_go_right();//S脱出
    go_follow();
    go_go_left();
    go_follow();//Q到着
    turn_rightL;
    Wait(360);
    Off(OUT_AC);
    turn_rightS;
    Wait(90);
    Off(OUT_AC);
    go_go_left();
    Off(OUT_ABC);
  }

 控えめに言って汚すぎて説明できない(おい)~
 インライン関数を本質的に理解してないんですが、サブルーチン同様に使えるのであれば、もっときれいに描けた。サブルーチン8つの壁…。~
 ということで、サブルーチンとインライン関数が同じように使えると仮定し、少し書き直したものをつかって改めて説明しようと思います。

*書き直してみた [#g57e30cb]


 int move_time;  // 整数型の変数を宣言
 move_time = 0; 

 この辺がどうなるのか根本的に理解してない気がする。不安。これできるのかな〜なんでRis解体してしまったんだ

**定義 [#ue0f0c45]
変更なし
 #define straight 5
 #define carb 2   
 #define KAITEN 2  //大きいギアを一枚しか噛ませられなかったので、回転を極力遅くしたかった。
                   //なお、1にすると今度は勢いがなさ過ぎてコップの収まりが浅く、抜けることが多かった。
 #define set_straight SetPower(OUT_AC,straight);
 #define set_carb SetPower(OUT_AC,carb);
 #define set_kaiten SetPower(OUT_AC,KAITEN);
 #define arm_tsukamu(t) set_kaiten; OnFwd(OUT_B); Wait(t); Off(OUT_B);
 #define arm_hanasu(t) set_kaiten; OnRev(OUT_B); Wait(t); Off(OUT_B);
 #define go_forward set_straight; OnFwd(OUT_AC);
 #define turn_leftL set_carb; OnFwd(OUT_C); OnRev(OUT_A);
 #define turn_leftS set_carb; OnFwd(OUT_C); Off(OUT_A);
 #define turn_rightS set_carb; OnFwd(OUT_A); Off(OUT_C);
 #define turn_rightL set_carb; OnFwd(OUT_A); OnRev(OUT_C);
 #define black 38                  
 #define glayA 42
 #define glayB 45
 #define glayC 48
 #define white 50 
 #define KURO 11
 #define TURN_TIME 90
 #define TUKAMU_TIME 3
 #define HANASU_TIME 3
 #define MA_NO_ZIKAN 3
 #define ma_wo_toru Off(OUT_B); Wait(MA_NO_ZIKAN);

**サブルーチンとかインライン関数とか [#dbdec9ad]
  sub go_go_left()
  {
    Off(OUT_AC);
    Wait(100);
    PlaySound(SOUND_FAST_UP); 
    go_forward;
    Wait(50);
    turn_leftL;
    Wait(TURN_TIME);
    Off(OUT_AC);
    go_forward;
    Wait(50);
  }

  sub go_go_right()
  {
    Off(OUT_AC);
    Wait(100);
    PlaySound(SOUND_FAST_UP); 
    turn_rightL;
    Wait(TURN_TIME);
    Off(OUT_AC);
  }

  sub go_go_forward()
  {
    Off(OUT_AC);
    Wait(100);
    PlaySound(SOUND_FAST_UP); 
    go_forward;
    Wait(50);
    Off(OUT_AC);
  }


 交差点で左行って右行って直進する(さっきと同じ)

  sub go_follow()//三秒間交差点ない前提でライントレースをする。
   {
    ClearTimer(1); 
     while (FastTimer(1) <= 300) {   //タイマー1を使用
      if (SENSOR_2 < black) {        //黒の範囲にいるとき、
          turn_leftL;
       } else if (SENSOR_2 < glayA) { //黒寄りのところにいるとき、
          turn_leftS;                      //少し左に曲がりながら、
       } else if (SENSOR_2 < glayB) { //白寄りのところにいるとき、
          go_forward;                      //直進し、
       } else  {                      //それ以外のとき、つまり白いところにいるとき、 
          turn_rightL;                     //大きく右へいきながら、
       } 
      Wait(1);                       //この判定を0.01秒ごとにする
    }
   }

  sub go_follow2()//ふつうのライントレース
   {         ClearTimer(0);
    while (FastTimer(0) <= KURO) {   //タイマー0を使用
     if (SENSOR_2 < black) {        //黒の範囲にいるとき、
      turn_leftL;
    } else if (SENSOR_2 < glayA) { //黒寄りのところにいるとき、
      turn_leftS;                      //少し左に曲がりながら、
       ClearTimer(0);                  //タイマーをリセットかける
    } else if (SENSOR_2 < glayB) { //白寄りのところにいるとき、
      go_forward;                      //直進し、
      ClearTimer(0);                   //タイマーをリセットする
    } else  {                      //それ以外のとき、つまり白いところにいるとき、 
      turn_rightL;                     //大きく右へいきながら、
      ClearTimer(0);                   //タイマーをリセットする。
    } 
    Wait(1);                       //この判定を0.01秒ごとにする
    }
   }

同じ。ライントレース。

  void go_follow3()//go_followの1秒バージョン
   {
    ClearTimer(1); 
     while (FastTimer(1) <= 100) {   //タイマー1を使用
      if (SENSOR_2 < black) {        //黒の範囲にいるとき、
          turn_leftL;
       } else if (SENSOR_2 < glayA) { //黒寄りのところにいるとき、
          turn_leftS;                      //少し左に曲がりながら、
       } else if (SENSOR_2 < glayB) { //白寄りのところにいるとき、
          go_forward;                      //直進し、
       } else  {                      //それ以外のとき、つまり白いところにいるとき、 
          turn_rightL;                     //大きく右へいきながら、
       } 
      Wait(1);                       //この判定を0.01秒ごとにする
     }
   }

 追加。C→Dで交差点後が少し3秒が長くD地点でぴたっと止まってくれない印象があった。→(&color(#c70067){関連1};)

  void go_follow4()//どうせ交差点後はこの組み合わせになることに気付いた
    {
     go_follow();
     go_follow2();
    }

  void go_follow5()//どうせ交差点後はこの組み合わせになることに気付いた 
    {
    go_follow3();
    go_follow2();
    }

 追加。すっきりさせたかったので。

  void tukamu()
   {
   repeat(6) {    //動く/とまるを瞬時に繰り返すことで、結果的に速度を落としたような動きを作る。
       arm_tsukamu(TUKAMU_TIME);
       ma_wo_toru;
      }
    OnRev(OUT_AC);//少し下がる(回転したりした時に他のコップに当たらないように。)
    Wait(80);
    Off(OUT_ABC);   
    turn_rightL;//アームの中でコップを狙いの位置へ誘導☆
    Wait(30);
    Off(OUT_AC);
   repeat(6) {  //※
      arm_tsukamu(TUKAMU_TIME);
      ma_wo_toru;
     }
    Off(OUT_B);//勢いが付きすぎると二個目以降はまだいいが、一個目が吹っ飛ぶ。
    Wait(5);//ここで一回勢いを殺すことで、一回目もちゃんと着地させる。
   repeat(3) {  //※
      arm_tsukamu(TUKAMU_TIME);
      ma_wo_toru;
     }
   }

 サブルーチンから変更。やっていることは同じ。
 一応繰り返しになりますが↓

 尚、全体的に速度/勢いを殺す動きをさせているが、勢いを殺し過ぎると二個目以降がコップにハマらなかったり浅いハマりで不安になることが多々。~
 ※のRepeatの数の比は重要。前の※が大きいとハメる予定のコップが勢い良すぎて吹っ飛び、後ろの※が大きいとハメ途中でハメられる予定のコップが逃げる。~

 ☆について
#ref(./1470986068Dp1oyA0_F5g2zKR1470986060.gif,50%)
 これの「上方に寄せる」ということ。これでコップが落ち着く地点にアームの長さが調整されている。


  void hanasu()
   {
   repeat(22) {  //アームを開ききるために、アームを閉じるときより+6〜+8長くして確実性を高める
    arm_hanasu(HANASU_TIME);
    ma_wo_toru;
   }
  }

   void turn_180()  //C/D地点でのターン用
   {
    turn_rightL;
    Wait(170);
    Off(OUT_AC);
    go_forward;
    Wait(50);
    Off(OUT_AC);
   }

 サブルーチンから変更。中身は同じ。

  void tsukande_hakobu()  //つかんではこぶ。うん。
    {
    go_forward;//少し前進しコップがアームに入るようにする(1)
    Wait(move_time);
    Off(OUT_AC);
    tukamu();
    Off(OUT_B);
    Wait(100);
    hanasu();
    Off(OUT_B);
    Wait(100);//コップひっくり返し完
    turn_180();//現在地点を出発
    go_follow4();
    go_go_forward();//交差点まっすぐすすむよ!
    go_follow5();//次の地点に到着
    }

  void tsukande_hakobu_last()  //つかんではこぶ最後六個目の時のみ。次の地点にいかない。
    {
    go_forward;//少し前進しコップがアームに入るようにする
    Wait(move_time);
    Off(OUT_AC);
    tukamu();
    Off(OUT_B);
    Wait(100);
    hanasu();
    Off(OUT_B);
    Wait(100);//コップひっくり返し完
    }

 大会時はサブルーチン8個むりだよふえぇってなってたのであんなに汚かったんです…~

( つかんで動く動きを部品化すればいいのでしょうが、intって使えるのだろうか…)

**たすくめいん [#vec1c783]

  task main ()
  {
   SetSensor(SENSOR_2,SENSOR_LIGHT);
    go_follow2();//本番でミスったのここ。交差点感知しなくて恥かいた。これで開始直後から交差点を感知してくれる。
    go_go_forward();
    go_follow4();
    go_go_forward();
    go_follow4();
    go_go_right();
    go_follow4();//Cに初めて到着
 
  int move_time;  // 整数型の変数を宣言
  move_time = 0;  //初回は地点についた時点でコップが収まっていることを狙う。
    tsukande_hakobu();
    tsukande_hakobu();
  move_time += 50;//並べたコップをとるために少し奥へ。短いとまあコップがアームに入らなくてむなしいことになる。
    tsukande_hakobu();
    tsukande_hakobu();
  move_time += 50;//並べたコップをとるためにさらに少し奥へ
    tsukande_hakobu();
    tsukande_hakobu_last();//Dで6つめを乗せおわる
    OnRev(OUT_AC);
    Wait(move_time);
    turn_180();
    go_follow4();//Sへ向かう
    go_go_right();//S脱出.ゴールへ向かい始める
    go_follow4();
    go_go_left();
    go_follow4();//Q到着
    turn_rightL;//コップが逃げないように基本右回りで行動。ぐるーり。バンパー参照
    Wait(360);
    Off(OUT_AC);
    turn_rightS;//コップが逃げないように基本右回りで行動。
    Wait(90);
    Off(OUT_AC);
    go_go_left();//コップを置き去りにし離脱
    Off(OUT_ABC);
  }

*感想 [#fdc942f1]
 恥かいて本当にしんどかった。プログラミングに関してほぼ一人で描いたのも時間取られたし。ハードは二人でできたからまだよかったが。まあ当日に手ぶらで来られるとは夢にも思っていなかったよ。というのが心からの感想。~

 最後先生のまとめの時に、「コンピューター制御がアテになると思いましたか」と投げかけられたとき、ただひたすらに震撼した。わたしは課題としてこの授業をこなしてきたが、確かにやっていることは「人の方がさっさとできるレベル」の簡単なことなのにかなり時間がかかったし悩むことも多かった。これが「人の代理(=人と同じレベルの行動)」や「人にできないことをさせる」こととなると、さらに複雑を極めるのだろうし、ミスがそれこそ言葉通り命取りになる展開があるのだろう。現代思想として「デジタルの方が確実」「コンピューターなら大丈夫」という風潮は確かにある。だがそこをこれからはリスクを少しでも考えるべきであるし、リスクを理解したうえで使いこなしてやれるよう、「コンピューターに利用されないように」利用していかなくてはとおもった。~


借り物
 歯車素材→http://www.pixiv.net/member_illust.php?illust_id=40748669&mode=medium

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS