ししかわです。
社員研修の一環で、マイクロマウスを自作して大会に出場しました。
全日本大会2020は終わりましたが、ブログはもうちょっとだけ続きます。
前回、リワークを経て基板が完成しました!
今回からマウスのファームウェアを設計・実装していきます。
方針
M5Mouseのコンセプトである「Web屋のためのマイクロマウス」を実現するために、次のルールを守って設計・実装します。
- 性能より保守性を重視する
- マウスの機能毎にモジュールを分割する
- オブジェクト指向にする。C言語を使うが、構造体と専用のメソッドの組み合わせで擬似的なクラスを作る。
- グローバル変数の濫用をしない
- ハードウェアアクセスは抽象化する(HALライブラリを使う)
- レジスタ直叩きの制御はPi:Co Classic3を使った研修で経験済みです。
- マウスの機能毎にモジュールを分割する
- コピペ禁止
- コードの意味を理解しないまま使わない
- そのまま参考にできるコードがあっても写経(自分でタイピングして写す)しながらやる
- コードの意味を理解しないまま使わない
設計
大きく、次のパッケージに分けてクラスを作ります。
- 迷路探索
- ドライバ
- コントローラ
- マウス
- 共通のユーティリティ群
簡易なクラス図を次に示します。
詳しい説明は省きますが、オブジェクト指向では「関心の分離」と「疎結合」が重要です。簡単のために関連の線のみ記述していますが、パッケージごとに責務を明確にしておくことで関心の分離を実現し、異なるパッケージ間を結ぶ線(関連)を最小限に保ち、クラス間の双方向の依存を無くすことで、疎結合が実現されます。例えば「迷路のソルバはコントローラやドライバの実装を見ない」ことで、迷路探索アルゴリズムの実装修正が走行に影響しないようになっています。
迷路探索
迷路探索を責務とするクラス群です。迷路の表現や、迷路探索アルゴリズムを備えたエージェントなどがあります。
エージェントは「迷路のマス」で座標を管理します。迷路を探索して解くためには「今何マス目にいるか」「現在座標の東西南北方向に壁はあるか」が重要で、「何メートル進んだか」「壁との距離は何メートルか」といった詳細には関心がありません。そのような細かい制御はMouseクラスの責務とします。
「迷路のマスの数」「迷路1マス分の幅」の情報はソルバ側で持っているので、このパラメータを変えれば異なる形状の迷路も走れます。M5Mouseの幅ならぎりぎりハーフマウスの迷路も走れる…はずです(未検証)。
当初の予定ではM5Stack側に迷路探索の責務を持たせて、M5StackとSTM32間で通信しながら迷路を走るつもりでしたが、工期が足りず、一旦すべてSTM32側に寄せました。今はM5Stackはボタン操作によって「走行開始」の司令を伝えるだけで、あとはSTM32で自動運転という作りになっています。
ドライバ
各ペリフェラルの駆動を責務とするクラス群です。エンコーダ、ジャイロセンサ、モータなどペリフェラル毎にクラスがあります。
各クラスはなるべくセンサ固有の値(例えば赤外線センサの生値)ではなく、物理量(例えば移動量メートル、角速度、壁の有無)を計算して返すようにして、デバイスが差し替わったときも他のクラスへの影響が出ないように気をつけます。
コントローラ
座標や速度値の制御を責務とするクラス群です。目標軌道の生成とオドメトリを用いた自己位置推定、そして目標軌道への追従を責務とします。
制御理論を勉強しながらの設計だったので、このあたりは最後までどう作るのが最適かわからず、手探り状態でした。今後も改善の余地が大きいところです。
マウス
直進や旋回動作、そしてドライバとコントローラを統合したマウスの機体制御を責務とするクラスです。Mouseクラスは先のエージェントと異なり、ミリメートルの距離で座標を管理します。1000Hzに設定したタイマで機体の制御ループを回します。
今回はここまで。
次回からは迷路探索、ドライバ、コントローラと制御ループについて解説します。