こんにちは。seyaです。
ロボットを動かすうえで制御は割り込み処理で一定時間間隔で行いたいということがあります。マイクロコンピュータではタイマ等を使用して一定時間ごとの割り込み処理を簡単に行うことができます。しかし、ラズベリーパイなどOSが積まれたものではOS上で動かしている実行ファイルからハードウェアの割り込み等を使用することは原則できません。
そこで、並列処理を行うことのできるマルチスレッドプログラムを実装することにしました。
はじめに、マルチスレッドプログラムを書く上で注意しなければならない点を以下にあげていきます。
- 共通の資源に複数の場所から同時アクセスをしてはいけない。
- 同じ変数に対して処理の順番が変わることで結果がかわるということを防ぐ必要がある。
- デッドロックが起きないようにする。
これ以外にもありますが、特に問題が起きやすいことは上記の内容になると考えられます。これらを防ぐためにはセマフォとミューテックスと呼ばれる方法があります。ラズベリーパイマウスで迷路を走行する上で、共通資源をアクセスするタイミングは次のものがありました。
- ペリフェラルの関数を使用するとき。
- printfやscanfといった標準入出力を行うとき。
- 一定時間で処理を行うために計測用の時間をラズベリーパイから取得するとき。
c++には標準ライブラリでミューテックスが提供されているためミューテックスを使用して排他処理を実装しました。
mutexをプログラムに読み込んで、mutexのクラスをグローバルで作成して、ひとつのmutexの変数をそれぞれのファイル間で共有しました。クリティカルな処理をする前にmutexクラスのlock関数を読み出して処理を行い、処理が終了後にunlock関数で処理を終了するというようにしています。
実装したプログラムのmain文はこちらです。
割り込み処理を実装したクラスとモード選択や実行を行うクラスをそれぞれ作成しておいて、それらのクラスの実態をグローバル変数として定義をして、スレッド用にセンサ割り込み、制御用割り込み、モード選択・処理用の関数をそれぞれ作成してスレッドを立てました。
マルチスレッドプログラムにして、センサで壁の有無を判定した結果迷路で走行することができるようになりました。
指定した距離を走るということ、90度回転するということ、迷路を走行することに関しては、マイクロマウスではじめよう ロボットプログラミング入門に丁寧に解説してあるので是非読んでみてください!
次回やること
壁制御を実装してマシンが区画の中心をまっすぐ走れるようにしていきたいと思います。迷路を走れるようになったので、走行の安定性を上げることが次の目標になりそうです。