All_outlook機体紹介 ー2022全国大会ー
全国大会お疲れさまでした!!
前回、「関東ブロックでボロ負けした」っていうブログを書いておきながら全国大会に行けることになり、行ってきました。結果は、良くて13位悪くて20位くらいかな。
ということで、今回は1年間私達が開発したロボットについてできるだけ全ての情報を公開していきます。
間違ったことを書いている可能性があるので、このブログの内容を鵜呑みにして作ってみたりするのではなく、ここで得た情報をもとに自分で深く調べて見るみたいな使い方でお願いします!
設計コンセプト
既製品は使わない
こんなコンセプトどうなの?感は否めないですがロボットを作る上でモタドラとかマイコンとかキッカーとかをつなげただけで動くのは当たり前でそんなのロボット作るとは言わない!(言います)という考えのもと既製品はジャイロセンサとOpenMV、超音波センサのみという頭の悪いロボットになってしまいました。
またマイコンもArduino Microなどは使わずにチップのAtmega328や328p、2560などを使用し周辺回路も全て設計しました。(マイコンに関しては別記事に)
ポスター
これみたら雰囲気わかるので、まずはこれを読んでもらうのをお勧めします。この後の文章読みずらいので。。
ちなみにSponsorに書いてある次世代ロボットエンジニア支援機構様からは、STEPというプログラムを通して、10万分の部品提供をしていただきました。 基本的にロボカッパーはみんな応募できるような応募資格になっているので資金が足らないという方は、文章書くだけなのでぜひ応募してみてください!
参考:https://scramble-robot.org/support_info/step2021/
モジュール紹介
はじめにそれぞれのモジュール(??)の回路とプログラムについて解説します。 ハードはfTomoが、ソフトはJunが書いてます。
ラインセンサ
ハード
使用マイコンーATMEGA 328
このラインセンサ一番の特徴が円形に32個も配置したセンサ(16個しか使われてない…)とフルカラーLEDです。
センサの読み取りにはフォトトランジスタの値を8chアナログマルチプレクサを使って読んでいます。センサ回路は特に書くことはないですね。一つ言うとしたら半固定抵抗は使わんってことですね。 実は値の調節用に半固定抵抗(しかもチップ)を載せてたのですが、使われることは一切ありませんでした。
デジタルで読むチームは絶対必要なんだろうけど、うちのロボットはアナログで読んでいるので、プログラム側でしきい値をいじってあげれば、いいのでマジで必要なかったです。しかも、自動しきい値調整も作ったし、まじでいらない。 By Jun
一番このラインセンサで時間を取られたのがフルカラーLEDの電源周りの不具合で、ロボット内でモータの次に電気を食ってるレベルで電気使います。そのため細い配線や弱い電源だとちらついたり色がおかしくなったりと不具合連発します。対策にコンデンサを増やしたりLED用に電源基板から直接電気を取るなどして安定した電源供給ができるように工夫しました。
おそらくほとんどのロボットはラインセンサのメンテナンス性は悪いと思います。(知らんけど)なので、動作確認は定期的にやっておくのがベストだと思います。実際このセンサは分解などで半固定抵抗が壊れて値が出なくなるトラブルが数回起こりました。これも半固定抵抗をおすすめしない理由ですね。
ソフト
うちのロボットのアウトオブバウンズ対策は、ラインセンサのみで行っています。超音波などなど載っていますが、それは違う用途です。
僕の記憶では、全国大会の全試合合わせて、ロボットがコート外に出た(故障含め)の5回くらいだったはずです。そのくらい正確に制御できてました。
どんなふうに実装していたのか紹介します。
まず、うちのラインセンサは直径約8cmの円周上にLEDと受光素子が32セット並んでいます。なんでこんなあるんでしょうね。ただの金の無駄遣いです。しかも、考えるめんどくさいし。
ということで、プログラム側では16個の値しか使っていません()ホントに無駄遣いですね。いや、最終的には32個使いう予定だったのですが絶妙に一般化できていない関数がいくつかあったのでめんどくさくて、16個です。
これでも全く問題なく動くのでオッケーということで。
そして、16個のセンサそれぞれからアナログ(0~1023)で値を取得して、あらかじめ指定しておいたしきい値と比較して、大きければ1、小さければ0にして、ラインの有無を判断します。
その後、円周上で一番大きい0の範囲のど真ん中が、ロボットがライン回避するために進むべき方向という処理をしています。
具体的には、正面から時計回りにそれぞれのセンサに対して0-15までのIDを振っておきます。反応が0と処理されたセンサ数をカウントしておいてその分の配列を用意して、0が出力されたセンサのIDを前から突っ込んでいきます。
その後、その配列を先頭からfor文で回して、今の値と次の値を比べて事前に作っておいた結果を入れるための配列に、差が1だったらとそれ以外だったらで分岐して値を処理します。
そして、連続数が一番大きいところを見つけ出して、そこのIDに定数をかけてあげれば角度が算出できます!!
これを読んでも意味わからないと思うのでもし、興味があったら実際のプログラムを見てください(そっちはそっちでよくわからないけど、)
あ、あと全国大会準備日の深夜にふと思いついて作ったしきい値を自動で決定するプログラムも入っています。
こいつのおかげでラインの検出精度が一気にあがりました。
具体的なアルゴリズムは、メインマイコンから合図となる信号が送られてきたタイミングから一定時間内(10秒)で検出した最大値と最低値を記録して、その差の1/3を最低値にたしたものを、しきい値としてEEPROMに保存するといったものです。EEPROMもこれで初めてちゃんと使ったのですが何事もなく上手く行ってくれて良かったです。
ボールセンサ
ハード
使用マイコンーATMEGA 2560
おいおいなんで2560使ってんだ と思う人も多いと思います。その訳は16個のセンサと16+2個のLEDを制御するためなんです。
センサは16個を等間隔で円形に配置したものでローパスフィルターなどは使わずに直接デジタルピンでパルスを読んでいます。
問題はLEDでボールの方向などがわかるように8こを円形にしたものを2つ配置しています。+2個はマイコンので動作確認などに使っています。
更にOpenMVがメインマイコンのポート数の関係でボール用のマイコンと通信できるようになっています。
ソフト
簡単に言うと、センサの値を読んで、ベクトル合成して、角度と距離出す、ごく普通の方法でやってます。
センサの値を読むフェーズは、初めはpalseIn関数でやってたんですけどあれは時間かかってしょうがなかったので、Tadaさんのブログを参考にして一気に読む方法にしました。一定時間、全センサをwhileとfor使ってデジタルで読みまくって、LOWだったらリザルトの変数にプラスしてくみたいな方法です。
値読んだあとは、そのまま全部で合成すると、壁との反射などで角度がおかしくなるので、最大値を出したセンサの周囲、5個のみをx軸、y軸に分解して足し合わせて、atan関数で角度を算出しています。分解の方は、事前に定数として、sinとcosの値を保存してあります。
距離は、最大値出したセンサの値をifでめっちゃ遠い、真ん中くらい、近いで処理しています。
ジャイロセンサ
ハード
使用マイコンーATMEGA 328
使用センサーMPU6050
メインマイコンではなくジャイロ専用にマイコンを用意しているのは昔センサの起動が遅いと思われてた時代にメインマイコンよりも先に起動させておくのに使っていた名残で今も別になっています。正直今はメインマイコンでいいらしい
ちなみにジャイロも8個の円形に配置したLEDがあって向きを8方位で表示することが可能になっています。
ソフト
完全にライブラリ任せです。ライブラリ神。
ホントはオフセットとかUIで出来るようにするべきなのですが、そんなにオフセットすることもないのでまだ実装してません。
ちなみにジャイロ専用のマイコンを載せているので、センサからi2cで値とって、角度出して、UARTでメインに送ってます。正直、メインで直で読むので十分です。まぁメインマイコンのループがどれだけ遅くなっても角度に影響でないので安心っちゃ安心だったかもしれない。メインループが遅いと他に影響出るからなんともいえないけど。
カメラ&超音波
ハード
使用マイコンーOpenMV H7 Plus
まあ回路は超音波センサ3つを直接つなげただけです。注意点はOpenMVが3.3V、超音波が5V駆動なところですね。超音波センサには5Vをしっかりつなげてあげてください。センサの値も5Vで出力されるのですが、OpenMVが全部のピン5Vトレラント対応しているので気にしなくでOKです。
設計上で工夫したのが後ろ向きの超音波センサでまっすぐに取り付けてしまうとゴールよりも高くなってしまいゴールを認識できなくなってしまいます。そこで10度ほど下向きに傾けてしっかりとゴールを読めるようにしました。
ソフト
ん?アルゴリズム??
飾りです。
カメラついてるだけで強そうな雰囲気でる。
あぁそういえば、ブロッカーで一瞬使ったけど超音波嫌い。
真面目なこと言うと、うちのロボットは中立点に置かれたときのゴール率がとてつもなく低いです。
まず、回り込みの精度をどうにかするべきってのはありますが、中立点はちょうどゴール端の真ん前に位置してるのでそれだけじゃだめなはずです。
こうなると、カメラでゴールの角度を認識してその方向にゴールするのがベストなのかな〜と思い、搭載しました。プログラム間に合わなかったけど。ラインセンサに時間かけすぎた。。
ボール補足センサ
ハード
なんとですねこの記事アルゴリズムがJunに書かれた後にハードを私が書いているのですが、書きたいことほとんど書かれてる!なんでなん?
少し補足しておくと受光側のセンサはラインセンサと全く同じ回路を使ってます。
あとレーザーを置く場所なかったので縦置きにして光を直角にミラーテープを使って曲げています。
ソフト
うちのセンサはレーザー使って光を絞って受光側に当ててます。なので、レーザーの少しのズレで受光素子に当たらなくなるので、素子を6つ並べてどれかには当たるようにしています。
受光素子それぞれからアナログで読み込んで、最大値を出したのセンサの値が一定値を超えていればボールが無いと判断します。
光を絞っているのでレーザーがあたっているときは相当、値が大きくなるので、ボールの光や環境に左右されることが少なくなっています。
無線通信
ハード
使用マイコンーESP32
ラジコン遊びにしか使われなかった不運のマイコンです。ESPってめちゃ安いから趣味でもよくつかいますが、自動書き込み回路がめちゃだるいです。あと3.3V駆動なので別に電源を用意したりレベル変換回路を用意したりと手間がかかって昔は不具合連発してました。自分でESP動かない時マニュアル作るほどでしたが、それ見たらなんとなく動くようになります。ふしぎだな~ (多分それも公開されるでしょう)
ソフト
ラジコンとして遊ぶのに使いました。
楽しかったです。
ちなみにコントローラーとして使っているのは、"Arduino Joystick"というやつです。簡単に使えて楽しい!
本日の進捗。
— All_outlook (@All_outlook) 2022年1月5日
やばいね。 pic.twitter.com/JF5he5jNNO
昇圧回路
ハード
使用ICーNJW4131
秋月のキットhttps://akizukidenshi.com/catalog/g/gK-07406/をパクったものですね
このキットは最大30Vなのですが頑張ってデータシート読みながら抵抗値変更したりして40Vまで上げることができます。
コンデンサは初期は2200μFを中期には4700μF✕2を後期は4700μF1個に落ち着きました。中期はパワーが出すぎてキッカーのテストを超えてしまってオーバースペックでした。今回の昇圧回路は出力調節なんてものはなかったので今後昇圧回路自作したいーみたいな人は絶対調節できるようにしましょう。
さらに過去キッカーを駆動させたときにロボットが動かなくなる不具合が多発したのですが、原因は電圧低下orソレノイドの逆起電力によるものだったと思います。そこで対策としてソレノイドの絶縁回路を組みました、ソレノイド動作時にPchMOSFETを使って全体の回路とソレノイドを電気的に絶縁することで動作時の電圧低下や逆起電力の影響が出ない用に工夫しました。この方法はコンデンサの容量を増やしたり、逆起対策のダイオードよりも難しいですがロボットの安定動作に欠かせないものだと思うのでぜひワンランク上の昇圧回路を目指してみてください。
またMOSFETの使い方を覚えたら色んなところに応用(LEDのONOFFやフルカラーLEDのONOFF、モタドラ)できるので、興味があれば勉強してみるのがおすすめです。
ソフト
まぁ何も考えず、補足センサの値を見て、ボールを一定時間補足していたら打ち込むようになっています。
キックするときも、一定時間放電し、その後4秒ほど待たないと次のキックが出ないようになっています。連発しているとなんかしらんけど、動かなくなるため。
モタドラ
ハード
使用マイコンーATMEGA328
こいつには苦しめられてきました。今まで4つもモタドラを作ってきましたがちゃんと動いたのはこの最後のものだけです。
過去の3つはモタドラとして製品になっているものでただマイコンとモーター、電源をつなげるだけのものです。なのに動かない、過電流保護が働くなどでまともに使えるものではありませんでした。今回のモタドラはハーフブリッジドライバとMOSFETから作るマジモンの自作モタドラで、まあこれにも動かないなどのトラブルが有りましたがMOSFETのゲート端子に繋がる配線を太くしたりコンデンサを5V系統と12V系統に各100μF載せたり対策をしてちゃんと動くようになってくれました。
ソフト
メイン側でそれぞれのモーター速度の目標値を決めてあげて、それぞれのモータードライバマイコンに送りつけています。
メイン側では、進行方向、傾き角度、スピードを入れてあげれば勝手に計算して送りつけてくれる関数を作ってあります。中身は普通に三角関数でいい感じにやってあげて、適当に合成して上げてます。
モータードライバ側では、送られてきた目標値をもとに、MDにPWMで送ってあげてます。周波数は今確認してみたらデフォルトのままでした。ここのマイコンでは、モタドラが壊れないように、正転後転切り替えが連続しないようにしたり、一気に加速したりしないようにしてたはずです。
ホントは、PWM周波数を下げると、もっと低速回転ができるようになることを確認(熱かったけど)したので、スピードによってPWM周波数を変更する処理を追加するべきだったかなーとか思っています。あと、正転後転切り替えの処理とかもっと攻められる気がしてたのでやるべきだったかな〜と思っています。
まぁモタドラ側のプログラムは12月頃から書き換えてないので色々直したいです。
電源
ハード
この基板はスイッチとヒューズ、電圧計、5V生成だけの簡単な作りになっています。
5V生成には贅沢にこのhttps://akizukidenshi.com/catalog/g/gM-06187/村田製のDCDCコンバータを使っています。(今見たら値上がり&在庫切れやん)正直こんなんじゃおすすめできないですね。
今作るならhttps://akizukidenshi.com/catalog/g/gM-06563/を2こ使うかなメイン基板とLED系統に分けて
絶対におすすめしないのが3端子レギュレーターです。どこかのくまちゃんが苦しめられてましたが、使うのは簡単なのですが発熱がひどく放熱が必要になる場合があるし効率が悪いしといいことないです。とは言うものの入力の電圧と出力の電圧の差が大きいと発熱が大きくなるので、電圧差の少ない5Vから3.3Vを生成するのに使ってたりします。
構造
インサートナット
こいつはいいぞ
半田ごてで温めながらニュって入れればいいので3Dプリンタとの相性抜群で整備性もナットが外れないので格段に上がります。
最初は難しいですが多分何十個もやるのですぐなれます
ちなみにAmazonのよくわからない激安のやつを使っています。全国大会前に追加するとき、ちゃんと見ないで買ったせいで、大きめのやつが届きました。ちゃんとした奴がいいならヒロスギとかで買うといいかも。あと、ヒロスギだとM2のインサートもあるらしい。使えるのかは知らんけど。By Jun
ハンドル
5mmアルミ棒を手で曲げてます。実はパイプじゃないんですねえ
固定方法は、棒の先端に穴開けてM3のタップを切って、直接ネジ止めしてます。この方法は非常におすすめしないです。ネジが緩みやすかったり一点に力が加わるので壊れやすいです。さらに試合後にハンドルが外れることもありました。こわいですねえ~
ということでおすすめしないハンドルでした。
バッテリーケース
軽量化のため穴を開けまくりました。三角形を意識して設計したのでそこまで強度不足も感じずに良かったです。
取り外しは手で回せるネジを一箇所取るだけですぐにできます。さらにネジなので外れることもありません。そしてXYZ軸すべて固定することで車検もしっかり通りました。おそらく上カバーがないと車検をクリアできなかったでしょう。
トップマーカー
このトップマーカーは結構人気でしたね。裏表に数字を書いておくことですぐに番号を変えることができたり結構利便性も高くできました。
ちょっと気にしないといけないところは3Dプリンタの関係でデータより小さく造形されるおそれがあるのでトップマーカーの直径を4cmよりも少し大きく設計するところです。(気にし過ぎか?)
ちなみにルールには " ~ referee to write number ~" と書かれているので、本来は審判が手書きできるようにしておかないとだめっぽいです。まぁ直接、試合結果にかかわることではないので緩かったんですかね。 そうなったとしても対応できるよう、無記入の円板も持ってってました。
オムニ
このオムニはこのチームができてから基本的には形状の変更もなく順当に進化した感があります。実はこのオムニ本番用ができるまでの仮オムニだったのですが本番用のオムニなんて作られることなく仮のもののままここまで来てしまいました。今回の大会用に新調したオムニはワッシャーをすべてのサイドホイールに付けシリコンの径も6mmから8mmに変更したり少しだけ過去のものよりも進化した…と思っていたのですが、いざ試合に出てみるとコートがワッシャーだらけじゃないですか!はい、うちのオムニです。本当に審判の方々相手のチームには迷惑をかけました。申し訳ございませんでした。
よしワッシャー全部取ったぞ これで迷惑をかけなくてすむ!…と思っていたのですがコートには白い粒がいっぱいじゃないですか!はい、うちのオムニです。今度はワッシャーがなくなった分サイドホイールに余裕ができて3Dプリンタ製のオムニに負荷がかかってしまい壊れてしまいました。
結果、前使っていたオムニに戻して一件落着 ちょっと、いや結構悔しい結果になってしまいました。
プログラム
通信について
マイコンが大量に載っているので通信を成立されるのがめちゃめちゃだるかったです。よくわからないし。正直、今もなんか知らないけど動いてるって感じです。
方式は全部UARTでやってます。基本的には、115200bpsで、ソフトウェアシリアルで受信するところは57600bpsにしています。
ちなみに並列でソフトシリアルで受信しようとすると使い物にならなかったです。使えるピンかな〜とか思って試したのですがだめだったです。要研究です。
なので、メインマイコン(ATMega2560)では、ライン、IR、ジャイロ、ESPの信号はハードシリアルで読んで、モタドラへの出力はソフトシリアルでやってます。
他のマイコン(ATMega328など)は、基本的にソフトシリアルで色々やってます。ソフトシリアルも1系統なら安定して使えるので良いです。
データは、それぞれ送りたいデータを1byteごとに丸め込んで送信しています。
例えば、ジャイロからメインは、0-360の角度情報を1.5で割って送信しています。ラインもおなじ方式です。
IRからメインは、ボール角度と距離を送りたいので、データ送信時に先頭に255を付けて、角度、距離、カメラからの値といった感じで通信しています。カメラからの値というのは、カメラをあとづけしたため、メインに繋げられなかったのでIRセンサに繋げたためこうなりました。
初めの頃は、SPIでやろうとしていたのですが、ブレットボード上ではできていたのに組み込んでみたら上手くいきませんでした。なので、SSとして使われていたところをソフトウェアシリアルして使うようにして、無理やりやったらうまく行ったのでずっとそのまま来ています。
今、よくよく考えるとソフトウェアシリアルにしたあと、マイコン電源にコンデンサを突っ込みまくったらうまくいくようになった気もするので、別にSPIは関係なかったんじゃないかなぁた思ったり。。。
SPIで動くなら、そっちのはうが速くて良かった気がします、、
スタートスイッチはトグルが一番!
初めの頃は、スタートスイッチをタクトでやっていたのですが、制御がめんどくさいし、不安定なのでトグルに変更しました。
毎ループ初めに、スイッチのつながってるピンを読んで、ifで処理してあげれば良いので最高です。
試合でスイッチ押すときにも、直感的にスタートしたり、ストップしたりできるので便利です。
タクトだと押しミスしたり、どのスイッチかわからなくなったりしてミスりまくっていたので、スタートは、トグル。他のUIはタクトかスライドがわかりやすくていいんじゃないかなと思います。
トグル最高!!
アタッカー
メインマイコンにそれぞれのサブマイコンから角度などの元データが送られてくるのでそれをもとに動かします。
受け取った角度データはジャイロの角度を引いてあげて、モーターへ出力するときは足してあげることで、コートの向きを基準とした角度軸で処理ができるようにしています。
また、その処理後のラインの値を保存しておき、毎回、前回の値と比較して、+130°〜230°の範囲になっていたら、もとの値に180°足すようにしました。
ここまでは、ブロッカーもアタッカーも共通です。
アタッカーは、まずラインが反応しているか確認して、反応していたら回避する方向へ進む、反応していなかったら、ボールの方向をもとに回り込み、姿勢制御を組み合わせて、動くといった処理になっています。すなわち、ラインの反応しているときは、他のことは何も考えずライン処理をするようになっています。
回り込みは、すごく適当なif文でやってます。全く正確じゃないです。一応、距離も使ってます。
今考えると、円と接線をちゃんと考えて、連続性のある関数を組むべきだなーと思います。今度、組み直します。
ブロッカー
いい感じのブロッカーできた!!! pic.twitter.com/gkwhobYCBN
— Jun (@jun_robot) 2022年4月28日
ブロッカーは、もともと超音波センサでやろうとしてたのですが、誤認識が多くてほぼうまく行きませんでした。
大会後に会場で教えてもらったラインセンサをもとにしたブロッカーを組んでみたらいい感じになったので紹介します。
やっぱり初めはラインセンサが反応しているかを確認します。反応していなかったら、前回反応していた方向へ進みます。また、反応が30°〜150°だったら45°へ、210°〜330°だったら315°へ進むようにして、角の部分で引っかからないようにしています。他の部分が反応していたら、ボールセンサの値をもとに、真横に動きます。
復帰したとき中立点からゴール前へ戻る処理と、一定時間ボールが動かなかったら攻撃する処理はまだかけていないので今度やります。
UI
幻のLCD&タクトモジュールは使わず、2つのスライドスイッチとトグルスイッチでやってました。
スライドスイッチ2つで4つのモードを作って、トグルの向きでそのモードの処理を実行するみたいなプログラムです。
今のモードの内容としては、アタッカーモード、ブロッカーモード(超音波)、ブロッカーモード(ライン)、ラインの閾値調整モードの4つになっています。今後はブロッカーモード(超音波)をラジコンモードにでも変えて、すぐに遊べるようにしておこうかなと思ったり。
ここまで読んでもらえばわかるように、スイッチ操作のみでアタッカーとブロッカーを変更できます。なので、試合中にダブルアタッカーにしたり、ブロッカーアタッカーにしたり戦術の幅が広がりとても良かったです。
あと、自動しきい値調整は短い時間にパソコンを広げなくとも、正確なしきい値にできるので最高でした。
おわりに
こんな感じで今年のロボットの紹介を終わりにします。
字が多く、読みにくくてすいませんでした。次はもっとわかりやすくしたいです。
何か質問とか、これはダメだろみたいなことがあったら、コメントかTwitterで教えて下さい。
最後まで読んでくれてありがとうございます!!
全国大会で試合したときの記念撮影。
楽しかったです!皆さんありがとうございます!!
三田学園物理部チーム「Re_X」
GUJO ROBO
KORRDET
Root41