fc2ブログ

紙式エンコーダの紹介

この記事はマイクロマウス Advent Calendar 2021の5日目の記事です。

昨日の記事は、らしゃ氏の「ロボコンに興味を持った中学生はどうなったか」です。
私も父親も、家電の調子が悪くなれば蓋をあけて...の人で、ごくごく普通のご家庭には"はんだごて"があるものだと思っていました。誤家庭であったようです。

■1.今年のテーマ
さて、このブログは年1回のAdvent Calendarを書くことが存在意義のようになっていますが...その話は置いておくとして、
今年は、新たに自作した”紙”式エンコーダを紹介しようと思います。推敲不足はご容赦ください。

■2.なぜエンコーダーを自作するのか?
マイクロマウサー(旧ハーフマウサー)は大抵の場合、完成品ではなくエンコーダを自作します。
その理由を明らかにし、紙式エンコーダを作るに至った背景を説明します。

マイクロマウスは壁に沿って走行しないタイミングがあります。
壁に追従しているだけでは走れないため、オドメトリをとって走行します。
オドメトリを求める際、機体のヨー角とタイヤの角速度を下記2つのセンサで測定することが主流です。

・機体のヨー角速度:MEMSジャイロ
・タイヤの角速度:ロータリーエンコーダーの微分

MEMSジャイロは4mm×4mmなど小さく軽いものが市販されていますが、
ロータリーエンコーダーの完成品は重く、大きいです。
そのため、マイクロマウス(旧:ハーフマウス)は小さく軽いエンコーダーを求め、自作することになります。

■3.主流のエンコーダー
主流のエンコーダーは2種類。(ほぼ1種類といっていいかもしれません)

方式①:磁気式エンコーダー
ほとんどの人が使っている手法
長所①:必要な精度を出すための知見がすでにある
短所①:磁石を使うため、モーターと磁気が干渉する※
短所②:磁石と磁気シールドが重い(左右両方で1.5gくらい)
参考:http://maimaimouse.blog.fc2.com/blog-entry-46.html

方式②:光学式エンコーダー
長所①:磁気式よりもさらにコンパクト、軽量に作れる
短所①:自作ではパルス数が分解能が高くなく、速度を得るには工夫が必要
参考:https://kojimousenote.blogspot.com/2015/11/blog-post.html

※エンコーダーにしようする磁石がモータの金属に引き寄せられる

磁気式で走れることはわかっていますが、磁石と磁気シールドのセット2つで1.5g程度あります。
システム全体で10g程度を狙うマイクロマウスでは大きな値ですよね?もっと軽くしたいと思いませんか?
磁気の干渉もいやですよね?
しかし、光学式は分解能が高くないため、速度を得るのに苦労しそうですよね?
⇒ということで、分解能が磁気式と光学式の間で、光学式レベルに軽量なエンコーダーを自作しようと思います。

■4.紙式エンコーダーの原理
発想は、こじまうすの光学式エンコーダーと似ています。

こじまうすの光学式は1回転のうちに何回か白と黒が切り替わるように歯をホイールに取り付けており、歯=白黒の切り替わりをフォトリフレクタで読み取ります。

紙式は(紙式も光学式といえるかもですが)、1回転で白から黒、またはその逆の変化となるように、グラデーションを印刷した紙をホイールに張り付けます。フォトリフレクタで紙から跳ね返る光量をはかることで絶対角を読み取ります。グラデーションを使うので、分解能を上げやすいです。(精度?知らない子ですね。何とかなるでしょう。きっと)

[Fig.1 ホイールに張り付けたグラデーション紙]
DSC_0249.jpg

さて、角度ごとにどんなAD値が検知さえるか見てみましょう。
測定方法はアナログです。(分度器やプリンタが無かったので、養生テープの芯と定規で頑張りましたが、それは別の話)

[Fig.2 タイヤの回転角度-AD値の取得風景]
FEKlN8GaIAAV6rC.jpg

タイヤの回転角度ごとのAD値はこちら

[Fig.3 タイヤ回転角度-AD値]
紙式エンコーダ_調査①

理想は|\|\|\|\ですが、/\/\/\となってしまいました。
グラデーション部分は単調減少で変化することがわかります。角度が読み取れそうですね。最も黒から最も白に切り替わる部分はなまされてAD値が変化することがわかります。問題になりそうです。この問題について次の章で対処していきたいと思います。

■5.紙式エンコーダは2つのフォトリフレクタが必要
AD値を角度に変換する際、AD値が○○の時は○degのようにテーブルを作り、AD値からテーブルを参照することで角度を得る手法がリーズナブルです。

前の章に角度ごとにAD値がどのように出るか調べました。

紙の色は最も黒から最も白に切り替わる部分(グラデーションでない部分)でなまされて変化するため、タイヤ1回転で2回同じAD値が存在することになり、AD値-角度のテーブルを作ることができません。テーブルを作成するのは、AD値と角度が一対一で紐づく必要があります。

そこで、最も黒から最も白へ切り替わる(またはその逆の切り替わる)側のフォトリフレクタを使わないようにします。つまり、Fig.3の赤で囲った部分は使わないようにします。そうすることで、AD値と角度が一対一の関係となるため、テーブルを参照し、角度を推定することができます。

しかし、最も黒から最も白へ切り替わる(またはその逆の切り替わる)タイミングで角度を推定できないくなります。そこで、半周ごとにフォトリフレクタでAD値を取得することを考えます。

タイヤ回転時の半周ごとにつけたフォトリフレクタ(以後、0位相とπ位相と呼ぶ)のAD値の変化と関係性を見ていきましょう。

タイヤをおおよそπ/2ずつ回しながらフォトリフレクタフードの写真を撮りました。少なくとも1個のセンサはグラデーション部分であり、最も白(または最も黒)から最も黒(または最も白)への切り替わりタイミングではないことがわかります。つまり、どの角度でもどちらか一方のフォトリフレクタのAD値で角度を推定できることが確かめられました。

[Fig.4 フォトリフレクタフードの様子]
2相の変化

■6.2つのフォトリフレクタからタイヤの絶対角度を推定する
今までの章より、2つのフォトリフレクタをのうち、どちらか一方はグラデーション部分(最も黒(または白)から最も白(または黒)へ切り替わらない部分)となり、交互に2つのAD値を使い、テーブルから角度を参照することで、角度を推定できることがわかりました。

具体的なソフトに落とし込んでいくため、次はAD値ベースで細かくみていきましょう。

タイヤの回転角毎の0位相とπ位相のAD値はθ-ADグラフを見ます。当たり前ですが、πだけ位相がずれて変化していることがわかります。また、写真で見たのと同様に、最低どちらか一方はグラデーション部分となっていることがAD値を見てもわかります。
※θ-ADグラフはわかりやすさのため、最も黒(または白)から最も白(または黒)へ切り替わるする部分はすでに削ってあります。

[Fig.5 0位相とπ位相のAD値の関係]
位相

0位相のAD値を横軸に、π位相のAD値を縦軸にプロットしたグラフがAD-ADグラフであり、このグラフを見ると、2つのフォトリフレクタのAD値の関係がより見やすいです。θ-ADグラフから角度ごとに0位相とπ位相の値を見てAD-ADグラフで追うと、タイヤが1回転するとAD-ADグラフでプロットが1周することがわかります。グラフ上の赤○と数字はその点におけるタイヤの角度を示します。

AD-ADグラフとθ-ADグラフのグラフは一部は薄赤、薄緑、薄黄で塗りつぶされています。それぞれの意味合いは下記となります。つまり、AD-ADグラフを見れば、どちらの位相のAD値を使えば良いか判断できることになります。

薄赤:位相πがグラデーション部分⇒位相πで角度推定
薄黄:位相0がグラデーション部分⇒位相0で角度推定
薄緑:位相0、πともにグラデーション部分⇒位相0、π両方で角度推定

プロットがあるにも関わらず、塗りつぶされていない領域があります。この領域は、角度が0.25~0.35と、0.75~0.85のどちらの範囲にいるかで薄赤か薄黄かが決まります。したがって、AD-ADグラフだけではどちらの位相を使えば良いか判断できない領域となります。直前の絶対角からどちらの範囲にいるか推定することで判断できます。しかし、電源ON時にこの領域にいると角度推定不可のため、角度が推定できるようになるまでタイヤを回すなど工夫が必要です。マイクロマウスはタイヤをモード選択のUIとしていることが多いので、どちらにせよ電源ON時にタイヤを回すことになるので問題にはならなそうですね。
・0.25~0.35の間の場合:薄赤相当で位相πで角度推定
・0.75~0.85の間の場合:薄黄相当で位相0で角度推定

[Fig.5(再掲) 0位相とπ位相のAD値の関係]
位相

直前の絶対角からどちらの角度の範囲か推定できるか検討してみましょう。検討パラメータは下記。
・最高速度:5m/s
・タイヤ直径:12mm
・制御周期:1ms
1周期あたりのタイヤの回転角度は、5m/s*1000/(12*pi)/1000=0.1326[rad/2π]
どちらの位相を使えば良いかその時の値のみではわからない角度は0.25~0.35と0.75~0.85であり、2つの期間の間の角度は0.4[rad/2π]。5m/sの速度で走っても問題なさそうです。

最後のグラフ"AD-θグラフ"を説明しておきます。このグラフは単純にθ-ADグラフの横軸と縦軸を入れ替えただけです。AD-θグラフからテーブルを作成し、AD値から角度を推定することになります。

役者はそろいました。
マイコンに実装する際はAD-ADグラフとAD-θグラフを使います。AD-ADグラフから、どちらの位相のAD値を使えば良いか判断し、判断した位相のAD値から、AD-θグラフをもとに、角度を推定します。両方の位相のAD値が使える場合は、どちらの位相から角度を推定しても同じような角度が推定されるはずです。適当に重みをつけて混ぜましょう。使う位相を切り替える際の値の飛びを防げるはずです。

[Fig.5(再掲) 0位相とπ位相のAD値の関係]
位相

長くなりましたが、紙式エンコーダの絶対角度の推定方法の説明は以上となります。

■7.紙式エンコーダの検知具合
紙式エンコーダで測定した結果を下記に示します。比較対象として前作の磁気式エンコーダの結果を乗せます。比較する量としては、今回と前回の角度から単純に差分をとって求めた速度を用いています。
式:速度[mm/s]=(今回角度[rad]-前回角度[rad])*6[mm]*1000[1/s]

Φ2[mm]を使ったノウハウがないころに作成した磁気式エンコーダとの比較なので、"まともな自作磁気式エンコーダ"と比較はできておりませんが、前作の磁気式エンコーダで走っていることから、今作の紙式エンコーダは問題なく走れると思われます。ただし、ブレは小さい方が良いわけで、加速度センサと相補フィルタをするなど、ブレの低減をしたほうが良いのかもしれません。

[Fig.6 紙式エンコーダと磁気式エンコーダの比較]
紙式エンコーダ

■8.紙式エンコーダに使った素子
紙式エンコーダには小さいスペースにフォトリフレクタを収める必要があります。ちょうどよいセンサーがありますので、紹介します。
サイズは3.2mm*1.7mm*1.1mmで表面実装のフォトリフレクタのモジュールです。
https://www.digikey.jp/ja/products/detail/sharp-socle-technology/GP2S60B/1642454

応答速度は1kΩをフォトトランジスタに直列につないだ場合で10μsといったところ。5m/sで走っているときの10μsでの角度変化は、
5[m/s]*1000[mm]/12[mm]/pi*(1/1000)*(1/1000)*10[μs]=0.0013[rad/2π]
フォトトランジスタの応答速度だけを考えた場合、5m/sで走った場合に10bit程度の分解能が得られることがわかりました。
応答としては十分そうですね。

[Fig.7 フォトリフレクタ応答速度]
フォトリフレクタ応答速度

ピンボケで申し訳ありませんが、メイン基板に立てた基板に実装しています。

[Fig.8 紙式エンコーダ用フォトリフレクタモジュール]
DSC_0256 - コピー

簡単ですが、回路図も公開します。電流制限抵抗は33.3Ωにしています。(なぜこんな抵抗値?と思うかもしれません。最初は100Ωで、弱かったので、1個並列でついかして、さらにもう一個並列に...の結果です)

[Fig.9 紙式エンコーダ用フォトリフレクタ回路図]
フォトリフレクタ回路

■9.Matlabのススメ
Matlab芸人まではいかないですが、マイクロマウス界のMatlab伝道師となりつつあるため、今回もMatlab活用を紹介しようと思います。

その①:エンコーダキャリブレーション
2つのAD値からどちらの位相のセンサーを使うのか、またAD値から角度を参照するテーブルをマイコンに書き込む必要があります。タイヤを空転させたときのAD値の時系列変化から、マイコンに囲む値やテーブルの自動生成をMatlabで行っています。


[Fig.10 Matlabによる紙式エンコーダーキャリブレーションの様子]
エンコーダキャリブ

その②:絶対角推定Cコードの動作確認
ソフトをマイコン上で直接デバックするのは大変です。そこで、作成したCコードをS-Function Builderを使ってSimulinkに組み込み、AD値の時系列データを流し込むことで正しく推定できているか確認しました。角度から速度を演算するアルゴもSimulinkでサクッと組み確認できました。
[Fig.11 Matlabによる絶対角推定Cコードの動作確認]
Cコード動作確認

■10.まとめ
長文になってしまいましたが、大きく分けると
①紙式エンコーダを作るに至った背景
②紙式エンコーダの角度推定方法
③検知具合の確認
④使った部品
⑤MATLAB活用事例
を紹介させていただきました。みなさんも紙式エンコーダにトライしてみましょう!

また、最後にですが、3月に2年ぶりの全日本大会が開催されます。
この前関西リアル大会に参加してリアルは良いものだなと思いました。
皆さん新作間に合わせましょう!楽しみにしています。

■11.明日は...
次の日はPIDream.net氏の「真上から迷路を撮影しよう」です。経路検知とか、トレーサーの判定とかいろいろ参考になりそうな記事です。楽しみにしています。



スポンサーサイト



市販のごはん

nano さんの記事のパクリ

■冷凍パスタ
マ・マーとSpa王が好み。でもSpa王の方が麺も味も良い気がする(好みか)

Spa王:海の幸のペスカトーレ ☆☆☆☆☆
https://www.nissin.com/jp/products/items/9920

Spa王:エビのトマトクリーム ☆☆☆
https://www.nissin.com/jp/products/items/9918

Spa王:ボンゴレビアンコ ☆☆☆
https://www.nissin.com/jp/products/items/9926

Spa王:あさりバター醤油 ☆☆
https://www.nissin.com/jp/products/items/9927

Spa王:彩野菜のぺペロンチーノ ☆☆
https://www.nissin.com/jp/products/items/9923

マ・マー:宮崎県産ほうれん総のバター醤油風味 ☆☆☆☆
https://www.nisshin.com/products/detail/4902110372397.html

マ・マー:4種魚介のペスカトーレ ☆☆☆
https://www.nisshin.com/products/detail/4902110372359.html

■袋めん(ラーメン)
ラ王の醤油が一番好み、評判の高いサッポロ一番の味噌があまりおいしく感じなかったのは
作り方が悪かったからだろうか?

まるちゃん製麺:醤油 ☆☆☆☆
まるちゃん製麺:味噌 ☆☆☆
まるちゃん製麺:豚骨 ☆☆☆
https://www.maruchanseimen.jp/index.html

ラ王:醤油 ☆☆☆☆☆
https://www.rao.jp/product/

サッポロ一番:醤油 ☆☆☆
サッポロ一番:味噌 ☆☆
https://www.sanyofoods.co.jp/products_search/?brand_category=01

■スープ
粉タイプが安くて定番だけど、フリーズドライタイプは具が多くてオススメ。
海鮮チゲスープは去年の夏のキャンプでたまたま買って旨さに感動してリピーターになったわけだが
どういうわけか最近はどこのスーパーでも見かけない。発売中止???

クノール カップスープ:きのこのポタージュ ☆☆☆
クノール カップスープ:トマトのポタージュ ☆☆☆☆☆
クノール カップスープ:オニオンコンソメ ☆☆☆
クノール カップスープ:コーンクリーム ☆☆☆
クノール カップスープ:ポタージュ ☆☆☆☆
https://www.ajinomoto.co.jp/knorr/cup-soup/

クノール フリーズドライタイプ:海鮮チゲスープ ☆☆☆☆☆
クノール フリーズドライタイプ:ふんわりたまごスープ ☆☆☆
https://www.ajinomoto.co.jp/knorr/freeze-dry/

まるちゃん 素材のチカラ:まいたけスープ ☆☆☆☆
https://www.maruchan.co.jp/products/search/sozainochikara_maitakesupu_5p.html

■野菜ジュース
大体この2本を日替わりで飲んでいる。
一時期はお得感で1000mlパックを買っていたが、際限なく飲んで腹をこわすので
200mlの飲み切りの紙パックで最近は飲んでいる。野菜ジュース飲みすぎると腹壊すんだよ...
野菜生活100はそろそろオリジナル以外も飲んでみますかね

野菜生活100 オリジナル☆☆☆
さらっさらだけど、スーパーとコンビニで飲んだ感じが若干違う
コンビニの方が、荒絞かんがあって好き。
https://www.kagome.co.jp/products/brand/ys100/

野菜一日これ一本 ☆☆
野菜ジュース界の天一。ドッロドロ。
https://www.kagome.co.jp/products/drink/A3363/

■リンゴジュース
個人的にはローソンが好き。(甘めの方が好み)ファミマとセブン逆だったかも
ローソン:甘め ☆☆☆☆
ファミマ:甘さはローソンとセブンの間+ちょっと果肉かん ☆☆
セブン:酸味おおめ ☆☆☆

■冷凍からあげ
あじのもと やわらか若鳥唐揚げ ☆☆☆
これは唐揚げではなく、「やわらか若鳥唐揚げ」なのだ。衣が唐揚げのそれではないのだが、まあうまい
https://www.ffa.ajinomoto.com/products/detail/id/297


ニチレイフーズ 若鳥の唐揚げ特から ☆☆☆
やわらか(ryよりは唐揚げっぽい。まあ味は同じくらい。量が多いので好んで買う。
https://www.nichireifoods.co.jp/product/detail/sho_id148/

■冷凍食品そのほか

ニッスイ ちゃんぽん:☆☆☆☆☆
野菜もたくさん、麺もうまい。長崎ちゃんぽん行かなくても良いのでは?
ただ、野菜の袋を開けるのが難易度MAX。普通に開けたら途中でビニールちぎれる。苦情こないんかコレ?
給湯器のお湯であれって、若干とかしてから開けるのがオヌヌメ
https://www.nissui.co.jp/product/00184.html

マルハニチロ:酸辣湯麺:☆☆☆☆
面が生めん感が結構あり、スープもとろみが程よくあり麺にからんでうまい
が、あっつあつで良く口をやけどする。
面が細めなので、手際良くやらないどデロデロに。
https://www.maruha-nichiro.co.jp/products/product?j=4902165167894

マルハニチロ:鶏ごぼう ごはん:☆☆☆☆
冷凍食品だとチャーハンがメインだけど、脂っこくないものが良いな~というときにオヌヌメ
https://www.maruha-nichiro.co.jp/products/product?j=4902165145458

あじのもと:中華丼の具:☆☆☆☆
冷凍の中華丼これいがい食べたことないので特にコメントなし
https://www.ffa.ajinomoto.com/sp/products/detail/id/12

■レトルトカレー
S&B カレー曜日 ☆☆☆
いたって普通のカレー。特段うまいわけではないが不通にうまい。
具がたくさんあるのがオヌヌメポイント。でも初めて食べた時よりコスト化っとなのか減ったんだよなぁ
https://www.sbfoods.co.jp/products/detail/16806.html

マイクロマウスって中央走行にこだわらなくても良いというお話

■Micro Mouse Advent Calendar 2019

この記事はMicro Mouse Advent Calendar 2019の16日目の記事です。

昨日の記事はInpさんの「2019年マイクロマウスクラシック機体紹介」でした。

最近はRAM容量の暴力を得るためにピン数を増やすことが流行っているとか。
ログに回せる容量沢山あればドラレコのようなログだったり、大会の最短走行4走分を記録したりできるので、できる幅が広がりますね!

だれか...SPI-FLASHを試しに使う人はいないものか...

■テーマ
さて、本題に入りましょう。私のタイトルは「null」でしたが、
特に意味はなくただ決まっていなかっただけです。

テーマは「探索時の位置補正について」です。

探索が安定しなくて困っている方はいませんか?
そんな方にヒントになればと紹介します。

■よくある探索時の位置補正
よくある位置補正では、横壁センサー(※1)を使って、壁のAD値が目標値に収束するように”壁に追従”することで、横位置(※2)を補正します。目標値は機体が迷路の区画の中央を走行するように設定されます。
以後、本記事では壁に追従する制御を”壁追従制御”、壁に追従し区画中央を走行しようとする制御を”区画中央壁追従制御”と呼ぶことにします。

※1)横壁との距離を、横壁に赤外線を当て跳ね返ってくる赤外線の強さをフォトトランジスで電圧として簡易的に距離を測定するセンサ。マイコンでAD変換を行い測定する。
※2)進行方向に対して直角方向の位置

区画中央壁追従制御では、図1に示すように横位置のずれが小さい場合はうまくいきます。


図1:よくある壁制御(ずれが小さいor無い場合)
20191216_図1:よくある壁補正①

しかし、図2のように横位置のずれが大きくなった直後にスラロームすると破綻します。
これは、区画中央壁追従制御により角度がずれたことに起因します。

ではなぜ角度がずれるのでしょうか?
マイクロマウスのような差動輪ロボットは横位置を直接補正することができません。
車を運転するときをイメージしてもらうとわかりやすいですが、横位置を補正するためにはヨーイングする必要があります。
つまり、いったん水平方向の角度をずらす必要があります。
また、横位置を補正する量が大きい場合、長い走行距離が必要となります。
これについても、1車線よりも2車線分レーンチェンジする場合により長い距離が必要なことをイメージしてもらえればわかりやすいかと思います。

つまり、横位置のずれが大きくなるとより長い距離壁に追従する必要があります。
しかし、図2のような横位置が大きくずれた直後にスラロームする場合、壁に追従できる距離が短いです。
そのため、横位置の補正が中途半端のまま区画中央壁追従制御が終わることで角度がずれます。

図2:よくある壁制御(ずれが大きい場合)
20191216_図2:よくある壁補正②

こうなっては、壁を使った制御をなくしたほうがうまく走るでしょう。
しかし、ずれが補正されないため、大きな迷路ではどこかで壁に衝突してしまうでしょう。

図3:壁追従制御なし
20191216_図3:壁制御なし


■区画中央走行にこだわらない
ではどうすればよいか?
答えとしては、テーマにある通り区画中央を走行することにこだわらないです。

横位置を補正するには一度ヨーイングが発生し、そのヨーイングにより角度がずれてしまう場合があることを説明しました。
つまり、横位置を大きく補正するためのヨーイングは悪なのです。

ではどうすればよいか?

マイクロマウスは迷路を走行するのでどこかでスラローム(90度旋回)を行います。
スラロームを行えば、補正したかった横位置は進行方向の位置となりますので、ヨーイングを発生させず補正することができます。

つまり、図4に示すように、スラローム後の直線走行を増減(※3)することで、スラローム前の横位置をヨーイング無に補正することができます。

※3)ほどんどのマウサーの方はスラローム前後に直線走行区間を設けていると思います。この区間を利用します。


図4:スラローム後直線増減による補正
20191216_図4:スラローム後直線補正

■でもやっぱり壁追従制御は必要
スラローム直後の直線走行距離を増減することにより、横位置を補正することはできます。
ただし、ジャイロのドリフトなどで発生する機体のヨー角を補正することはできません。
結局は壁追従制御に頼ることになります。(壁追従制御をなくすこともできますが、またどこかで)

横位置はスラローム後の直線走行で、ヨー角は壁追従制御で補正することを考えます。
これは、区画をまたいだ際の横位置をその区画内で変わらないように制御することで角度のみを補正できます。
つまり、迷路の区画をまたぐ毎に、またぐ際のAD値を目標値として設定し追従することで、横位置を変えずにヨー角のみを補正することができます。

実は...
区画中央壁追従制御は、横位置が大きくずれた場合に破綻しやすいですが、ジャイロのドリフトなどによるヨー角のずれも一緒に補正されるため、便利な補正方であったのです

■まとめ
多くの方は壁に追従し区画中央に戻す制御(区画中央壁追従制御)を行っていると思います。
しかし自分はハーフサイズではうまくいかなかったため、下記の制御を行っています。

補正を横位置とヨー角別々に行う。
横位置はスラローム後の直進走行距離を増減することで、
ヨー角は区画マタギの際の横壁AD値を目標値とする壁追従制御で行う。

では、良き探索ライフを!

明日の記事はmakoさんで「機体紹介」です。
0時投稿を目指していたら、遅くの投稿となって申し訳ない!




探索がんばるぞい

■はじめに

この記事はMice Advent Calendar2018の5日目の記事です。
前回の記事はコヒロさんの謝罪会見でした。

コヒロさんの作成するハードは美しく、”走ったら速そう”と毎回思っています。応援しています!

コヒロさんはどちらかというとハードが得意とのことですが、私はどちらかというとソフトかなと。ソフトを改良したくなり新作ハードが疎かになってしまう人種です。

限界性能でみると、ハードの問題はソフトで取り返しがつかないんですがね...

■挨拶
お久しぶりです。しゅべるま~ことY.I.です。
全日本大会お疲れさまでした。
といっても私は最後まで参加できなかったわけですが...
去年は抗生物質の副作用によりフル欠席、今年はカンピロバクター腸炎により早退です。私、呪われているんでしょうか???

今年の成績は
マイクロマウスファイナル:9位
マイクロマウスクラシック:12位

新作作っていないと置いて行かれますねぇ~
ただ、32×32で危なげなく探索できたってのは結構満足です。
来年こそは新作を!


■本題
ハーフマウサーが増えて欲しいので、ハーフでいかに探索を安定させるかについて書きます!

■壁の位置や角度を利用した補正」
マウスをある程度経験すると”壁への追従制御”だけでは限界が見えてくると思います。特にすべるような場合。そこで壁切れ補正とか前壁補正とか出てくるわけですが。

私が探索時に行っている壁利用した補正を箇条書きします。
これだけ行えば、ほぼすべての区画で補正が行える気がします。
全部で11個ありますが...。私のハーフは素性があまり良くなく、これだけしないと探索が安定しなかったのです。

①区画に入った直後の左右壁センサ値を取得し、これを壁追従制御※のリファレンスとする。

②スラローム時、前距離走行時の横壁位置を用いて後距離を補正

③スラローム時、前距離走行時の前壁位置を用いて前距離を補正

④スラローム時、前区画での横壁位置を用いて後距離を補正

⑤スラローム時、前区画での柱位置を用いて後距離を補正

⑥袋小路進入時、前壁位置を用いて前後位置補正

⑦袋小路での停止時、前壁角度を用いて機体ヨー角を補正

⑧袋小路脱出直後スラローム時、袋小路進入時の横壁位置を用いて後距離を補正

⑨3区画直進連続時、前区画および前々区画にて左右ともに壁がなかった場合、柱位置を用いて機体ヨー角を補正

⑩スラローム時、前区画および前々区画にて直進かつ左右ともに壁がなかった場合、柱位置を用いてスラローム角度を増減(機体ヨー角を補正)

⑪直進時、壁切れにより機体前後位置を補正。

※壁追従制御:横壁センサがリファレンス値に収束するように機体のヨー角を制御すろこと

こまかな説明は割愛します。意味、実装方法は考えてみてください。

なにかこれ以外のアイデアで探索時の角度や位置を補正してるって方がいたら是非教えていただきたいです!

■導入結果


■最後に
これからエキスパートはハーフの時代です。
来年のマイクロマウスファイナルでお待ちしております!
(これで私が行けなかったら恥ずかしい...)

さて、明日の担当はqtfdl94qさんで「piyo」です。
どんな内容かさっぱり見当がつきませんね。(私が言えませんが…)

Embedded coderを使おう!


こんにちは

今回の内容は「embedded coder」を使ってSimulinkによるマイクロマウスの制御プログラムを作ろう!です。
最初は一つ一つの設定の意味とか詳しく解説しようと思ったのですが、設定項目が多いので
動画で許してください(笑)

「embedded coder」はMathworksによるマイクロマウスへのライセンス提供に含まれております。
インストールされてなければ、インストールしていないツールボックスをすべてインストールしましょう!

「embedded coder」を使った制御プログラムの作成は下記の流れとなります。
③については、⑤で結果に差異が出た場合に行えばよいと思うので、飛ばしていいと思います。
※下の①や②の番号と第一章、第二章は対応しないです。

①Simulinkでモデル作成
②モデルをビルドし、auto codeの生成
③visual studioやs-fuctionでauto codeをコンパイルし、simulink上の実行結果と差異がないかの確認
④マイコンのプロジェクトにauto codeを組み込みビルド
⑤マイコン上で実行し、simukink上の実行結果に差異がないかの確認


第1章:初期設定,ビルドの確認



■(00:00~01:00)プロジェクトを新規に作り、簡単な入出力を作る。
・auto codeの関数の入出力設定をするために、事前に入出力を作る必要がある。

■(1:00~1:30)信号の型名の要素数の表示設定、信号の型の設定
・組み込みではdoubleでなくfloatを使用することや、とりあえずintではなくcharやshortのように型を正しく設定する必要があるのでsimulink上でも型を指定します。また、型をすぐに確認できるようなsimulinkの設定を行います。

■(1:50~9:30)コンフィギュレーションパラメータの設定
・細かいことは割愛しますが、重要な点だけ。
・動画上で行っている設定はデバッグ用のcodeを出力する設定です。モデルとコードの整合が取りやすく可読性は良いですが、RAM効率、実行効率は良いとは言えません。この設定で十分マイコンで動くなら良いですが厳しい場合は、コード生成->最適化にて設定を調整することでRAM効率、実行速度を向上させることが可能です。
・一番最初にコード生成にて、シミュレーションターゲットファイルのを「embedded coder」に設定することが重要です。「embedded coder」に設定しないと出てこない設定項目があるのでい一番最初に行うことをお勧めします。
・最初に簡単な入出力を作成しましたが、コード生成->インターフェース->モデルの関数を設定にて、関数の入出力を設定できるようにするためです。

■(9:30~11:00)ビルド&RAM容量とauto codeの確認
・Ctrl+Bでビルドができます。
・ビルドするとレポートが出力され、必要なRAM容量が解析されます。
・TestAutoCode_Pという構造体変数にgainの設定値が格納されていることがわかります。今の設定だとRAMに確保される状態です。gainを実行中に変更したい場合はこのままでも良いですが、正直constに設定したいところです。(次にその方法を紹介します)

■(11:00~11:30)const、volatileの設定
・コード->C/C++コード->コードパースペクティブでのモデルの構成で設定を行います。(あれれ、おかしいぞ、設定ができない。次の動画へ続く)

第2章:変数の修飾子(const,volaitle)の設定,サブシステムの設定



■(00:00~00:30)const、volatileの設定(続き)
・Embedded coder ディクショナリてのを一回開くと設定できるようになるそうです。
・お好みでvolatileとconstを設定しましょう。

■(00:30~01:30)再度ビルドし、volatile、constになっているかを確かめる
・volatile constでgainの常数が格納されていることを確認。

■(00:30~05:30)サブシステムの取り扱い
・題目とは関係ないですが、情報表示->自動生成名の非表示のチェックを外すのが良いです。
・Atomicサブシステムとして扱うにチェックがないと、サブシステム含めすべてが1つの関数にベタっと書かれます。
・Atomicサブシステムとして扱うにチェックを入れ、関数のパッケージ化を「再利用できない関数」に、そのほかを適当に設定すると、サブシステム名(今回はSybsystem)のcとhファイルが作られ、構造化されます。(なんで計算結果をグローバル変数で渡すんだろう...)

第3章:バスオブジェクト(構造体)
・3:30~4:00のエラーは見逃してください...操作ミスです。



■(00:00~01:25)バスオブジェクトの作成
・入出力が増えると、いくつかの信号をまとめて構造化したいと思います。C言語の構造体がSimulinkではbusに当たります。
・モデル内のみのバスは事前定義が不要ですが、モデル全体の入出力となるバスにはC言語のように事前の定義が必要です。
・バスの事前定義にはバスエディタを使用します。(編集->バス エディタ)
・バスエディタでは、各エレメンツの型を次元(配列の要素数)を設定します。
・バスエディタで変種すると、ワークスペースに変数が出力されます。ctrl+Sをしても保存されないことに注意です。変数を直接名前を付けて保存しましょう。

■(01:45~05:10)バスオブジェクトにしたがったモデルの作成
・In1の出力をバスエディタで設定したバスオブジェクトとします。
・Out1も同様に設定すべきですが、ここでは忘れています(信号が1本だったのでエラーが出ていない)

■(05:10~05:20)バスオブジェクトがワークスペースにない場合
・モデル内にバスオブジェクトを設定したのに、ワークスペースにバスオブジェクトが存在しないとエラーが出ます。モデル内ではワークスペースにバスオブジェクトを見に行くことがわかります。

■(05:20~06:50)バスオブジェクトの自動読み込み設定
・先ほどバスオブジェクトを”test_bus.mat”で保存したので、そのmatファイルを読み込むmファイルを作成し、set_simulink.mで保存します。
・作成した、mファイルをモデルを初期化する際に自動実行するように設定を行います。ファイルをファイル->モデル プロパティ->モデル プロパティで出てくるウィンドウのコールバック->InitFcnにset_simulinkと書くと、set_simulink.mが自動実行されます。

■(05:20~08:20)信号名とバスオブジェクトのエレメンツ名の不一致
・先ほど忘れていたOut1にバスオブジェクトを設定します。
・信号名とバスオブジェクトのエレメンツ名と異なる状態でビルドするとエラーが起きます。
・信号名を修正し、エレメンツ名と同じとするとエラーが解消されます。

第4章:マイコンへの組み込み



■(00:00~01:50)作成したモデルのSimulink上でのシミュレーション
・時間刻みを変数DTとし、set_common_param.mで保存します。
・set_common_param.mをset_offline_param.mで呼び出すようにします。
・simulink上でのシミュレーション終了時間をSIM_ENDとし、set_offline_param.mで保存します。
・simulink上でのシミュレーションするための信号を、set_offline_param.mで保存します。
・先ほどのように、InitFuncのコールバックにてset_offline_param.mを呼び出すように設定します。
・mファイルよりこのモデルのシミュレーション行いとりあえず結果が出ました。

■(01:50~06:21)ビルドし、マイコンに移植
・マイコンに移植するようのモデルを開きビルドします。このモデルにあるサブシステム「ControlModel」は先ほどシミュレーションした”オフライン用”のモデルと共有化されています。(共有化の方法はまた後程)
・生成されたファイルはたくさんありますが、必要なのはert_main.cを除いたhファイルとcファイルです。これらのファイルをマイコン用のプロジェクトに登録します。(動画では登録済み)
・インクルードするヘッダーファイルは1つでよく、simulink名.h(この場合はtest_auto_code.h)です。
・入力と出力用の構造体はsimulink名_types.hにあります。この構造体の実態をどこかで確保します。
・起動時に1回だけsimulinl名_initialize()を実行します。
・制御周期毎に入出力用の構造体ポインタを引数として、simulink名_step(&output,&input)を実行します。(動画ではwhileループ。本当は割り込み関数が良い)
・動作確認のため、入出力用の構造体のメンバの値をUARTで出力するようにする。

■(06:21~07:05)書き込み&実行
・tera termでurat経由でマイコン実行結果を取得

■(07:05~10:00)マイコンでの実行結果とsimulinkでの実行結果を比較
・tera termで取得できた文字列をcsvとして保存し、matlabでcsvを配列として読み込む
・simulinkの実行結果とcsvから読み込んだ結果を比較し、おおよそ一致していることを確認(グラフを重ねるべきだが面倒なので割愛)


以上の流れを行えばとりあえずsimulink上でマイクロマウスの制御ロジックの構築はできると思います。
下記については気が向いたら書こうと思います。
・マイコン用のコード生成用のモデルとシミュレーション用のモデルの共有方法、
・auto codeでインクルードされるを自作関数に置き換える方法(simulinkに機能がある。)

では、良きモデルベース開発を~

そうそう、ハクメイとミコチってアニメ化された漫画ありましてですね、おすすめなので是非!!!




プロフィール

tennisyi

Author:tennisyi
現在、東京理科大学miceに所属しており、マウスを制作しています。
目指せハーフマウス脱初心者!

最新記事
最新コメント
最新トラックバック
月別アーカイブ
カテゴリ
検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム

この人とブロともになる

QRコード
QR