あきらぼ

テック系ブログ

カルマンフィルタの復習

こんにちは。

 

先日、会社でカルマンフィルタの話がでて、ざっくりとしか説明できなかったので復習しようと思い教科書や動画等を色々見て分かりやすいものをいくつかピックアップしました。

カルマンフィルタとは?

カルマンフィルタのあくまで個人的な理解にはなりますが、

複数の精度の異なる情報源(制御値やセンサー値)を用いてシステムの状態を最適に推定するためのフィルタ

だと思っています。

 

一体どういった事例に適用できるのかというと私が良く聞いたことがあるのは、

航空機や自動車でのGPSINS航法が多いでしょうか。

 

航空機や自動車の自己位置を推定しようとするときにGPSは簡単にイメージが付くと思います。

しかし、GPSは更新頻度が低かったり(1Hz)、トンネル等電波の入らない場所に入ってしまうと機能しなくなってしまいます。

 

また、IMUセンサー(慣性)を用いることによって、加速度や角速度から移動量を推定することで自己位置を推定することができます。

こちらの方法では数百Hzでの慣性センサの情報を使って速い位置推定を可能としますが、ノイズが多く、位置は積分をして求めるので時間がたてばたつほど誤差が蓄積されてしまいます。

 

カルマンフィルタではこういった複数の確からしさ(確度)の異なる情報を確率的に統合して最適な推定値を算出してくれます。

この時に重要になるのが、推定値の誤差です。

この誤差をカルマンフィルタでは正規分布として処理することで簡単に計算できるようにしています。

だからこそ、マイコン等の処理能力の低い計算でも実装することを可能としています。

 

カルマンフィルタの理論

復習としてまず、読み直したのが、こちらの本です。

 

私は2014年に購入していますが、いまだにAmazonで検索するとトップに出てきますね。

 

こちらは基本的な理論を説明してくれています。

なので、現実問題に実装だけできればいいのであれば特に読む必要もないかなと思います。

 

次に、Youtubeでも割と分かりやすく理論を説明してくれている動画があったので紹介します。

 

www.youtube.com

 

動画で無料で勉強できるのは便利な時代ですね。

 

カルマンフィルタの応用

次に、理論は分かったが現実のどんな問題に適用できるんだよというところで非常に分かりやすい動画があったので紹介します。

この動画は学生時代に見たかった内容ですね、、、

www.youtube.com

 

現実問題への適用とリアルについて非常に分かりやすく説明してくれています。

 

最後に複数のセンサー情報を用いて自己位置推定するという現実問題が大きな技術的課題となる自動運転におけるカルマンフィルタの応用事例を説明してくれている記事があったので紹介します。

こちらはティアフォーという日本の自動運転ベンチャー企業のテックブログ記事になります。

tech.tier4.jp

 

以上、学生時代ぶりにカルマンフィルタを勉強しなおしたときに参考になったので紹介しました。

次回は私も、なにか現実問題に対してカルマンフィルタを実装してみますかね。

 

RaspberryPiでBME280で気圧測定

今回は気圧センサーであるBME280を使って気圧測定をしました。

 

最近梅雨入りしたせいで、ニュース等でも天気病などといって、気圧の低下に伴う体調不良が取り上げられるようになりました。
この天気病は気圧の絶対値ではなく、変化量が重要だと考えられています。

 

 

 

そこで、実際に時系列の自宅の気圧データを取得することで体調管理をしましょうというのが目的です。
完成形はこちらです。

 

 

さて、実際に実装に移っていきます。

BME280とRaspberryPiはI2Cで接続しています。

詳細はこちら

aki-lab.hatenadiary.com

 

今回使用した気圧センサーはドイツの自動車部品メーカーのボッシュ製のBME280になります。

ACEIRMC BME280搭載 温湿度 気圧センサーモジュール 5V用 SPI I2C Arduino対応 Raspberry Pi (1個)

 

データシートはこちらになります。

https://www.bosch-sensortec.com/media/boschsensortec/downloads/datasheets/bst-bme280-ds002.pdf

 

基本的にはこちらのデータシートの指示通りにレジスタを叩いてデータを取得していきます。

 

まず、実際のコードがこちらになります。

 

基本的にはデータシート通りの実装なのですが、pythonで記述する際に、変数の型が明示的ではなかったので、Numpyを使用して明示的に型変換を行うことでデータシート通りの温度と気圧の補正を行っています。

 

実際に実行するとこんな感じです。

pi@raspberrypi: python3 BME280.py
Device ID is 0x60
BME280 is connected.
Temperature 26.88 degC
Pressure 998.76 hPa

こちらの温度は気圧センサ補正に使用しているのでセンサーの温度です。

なので、室温よりは少し高い値になっているので単純な環境センサ値としては使えなさそうです。

 

あまり、レジスタ直叩きで使用している記事を見なかったので参考になればと思います。

 

実際に使用してみると、天気とは関係なく気圧が変動していることや、気密性の高いマンションだと換気扇を使うことで圧力が下がってしまうことです。

次回、頭が痛くなったときは値を確認してみようと思います。

 

コードの全体はこちらになります。

GitHub - Aki-R/CCS811_BME280_RPi: Upload CCS811 and BME280 measurement to database by using RaspberryPi

 

 

STM32 Nucleo でCO2センサーCCS811を動かす

こんにちは

今回はSTM32マイコンの評価ボードであるNucleo F401REで環境センサ(CO2センサ)であるCCS811を動かしてみました。

背景

最近在宅勤務が増えて、ワンルームマンションで一人暮らししているのですが、長時間家に籠りっぱなしになるので気分がすぐれない気がするときが時々ありました。
築浅のマンションで気密性が無駄に高いので換気ができていないのが原因かと考えました。

そこで部屋のCO2濃度を計測し、在宅勤務中の換気の目安にしようと考えたのが始まりです。

システム構成

今回使用したのは以下になります。

  • CCS811 CO2センサー
  • Nucleo F401RE

実際のボードはこちら SparkFun gator:environment - micro:bit Accessory Board - スイッチサイエンス

今回はただの動作確認なのでこんな感じのシステム構成です。
f:id:AKIRA_san:20220309224715p:plain

前準備

今回購入したCCS811とBME240のボードなのですが、スルーホールのサイズが特大で普通のピンヘッダをそのまま半田付けするだけではブレッドボード等でも使えません。
そこで、ユニバーサル基板を使ってちょっと無理矢理にピンヘッダをはんだ付けしています。

f:id:AKIRA_san:20220309231518j:plainf:id:AKIRA_san:20220309231511j:plain

あとは要らないユニバーサル基板の部分をカットします。
ニッパーで切ったのですが、安物じゃなくてちゃんとしたニッパーが欲しくなりましたね(笑)
ちょっと高いけれど掴みもの定番工具メーカー、Knipexとか。

 

あとはNucleoの3.3V, GND, SDA, SCKにセンサーをつなぎます。
f:id:AKIRA_san:20220309232032j:plain

ここで後になって気づいたのですが、I2Cの信号線のプルアップ抵抗を設置していませんでした。
データシート上は4.7kΩを使うそうですが無いので10kΩの抵抗で代用。(一応問題なく動きました。)

f:id:AKIRA_san:20220309232327j:plain

これで前準備は終了です。

STM32CubeIDEでソフト作成

次に今回のCO2センサーの値を取得してPCに出力するためのソフトを作っていきます。
数年分にSTM32を触ったのですが、友人からCubeという便利なSTM32用のIDEがあるというので今回はそれを使ってみます。

www.st.com

イントールして新規STM32プロジェクトを作成します。

f:id:AKIRA_san:20220309233043p:plain

次に今回使用するNucleo F401REを選択します。

f:id:AKIRA_san:20220309233240p:plain

次にGUIでGPIOのピンアサインの設定をしていきます。
(ここでの設定が勝手にコードとして出力されます。)
この機能がこのIDEで非常に便利でよかったです。

まずはI2Cの設定。
I2C1を使用するので有効にするためにI2Cを選択します。
選択すると右側のピンアサインの図も更新されてI2C1のピンができました。

f:id:AKIRA_san:20220309233638p:plain

次にPCとのシリアル通信のためにUSARTを有効化します。 同様にUSART2を選択してModeをAsynchronousに変更します。
パラメータSettingでボーレート等も設定できます。

f:id:AKIRA_san:20220309233829p:plain

あとは設定を保存すれば今設定した内容は勝手にコードとして既にmain.c, main.hに定義されています。

次に実際にコードを書いていきます。 全体は以下のGitHubに保存しています。

github.com

今回参照したDocumentは以下です。

CCS811データシート https://cdn.sparkfun.com/assets/2/4/2/9/6/CCS811_Datasheet.pdf

STM32 F4 HAL ドライバーリファレンス https://www.st.com/resource/en/user_manual/dm00105879-description-of-stm32f4-hal-and-ll-drivers-stmicroelectronics.pdf

基本的にはHALのいくつかのI2C、UART用の関数を使えば簡単に使えるようになります。

まず必要なレジスタアドレス等をmain.hで定義します。 User Codeの部分に追記します。

次にmain.cのUser Codeの部分にレジスタへの処理を色々と書いていきます。

CCS811の使い方としては電源を入れたら、まずブートモードに入っていて計測できないので、計測モードを開始させる必要があります。 ブートモードから計測モードにするためには「APP_START:0xF4」を呼び出す必要があります。(こちらのコードでは69行目で行っています。)

次に計測モードにしたら計測モードを設定する必要があります。 4つのモード(アイドルを含めたら5つ)があり、計測周期や消費電力が異なります。

今回はモード1を選択しています。

あとは周期的にデータを受け取ってはPCに出力するようになっています。 ほんとはデータ取得時にデータが更新されたかどうかのレジスタを確認した方がいいですが、今回はパス。

動作確認&実際に使ってみて

実際に動かしてみるとPuttyで問題なくデータを確認できました。 f:id:AKIRA_san:20220310000535j:plain

このセンサーは計測モード設定後20分は正しく計測ができないので、注意が必要です。
また、初めての使用開始から48時間はエイジングが必要とのことで最初は動かし続ける必要があります。

実際に在宅勤務中や部屋で作業中に二日ほど使用してみました。 結論から言うと、換気の目安には使えそうにありません。

このセンサーはCO2を直接計測しているわけではなく、揮発性有機化合物から換算したCO2濃度を出力しています。 そして、この揮発性有機化合物は部屋を換気しないと確かに増えるのですが、臭いに対して非常に敏感です。 なので食べ物やにおいのある飲み物を近くに置いたらあっという間に値が跳ね上がります。(ex. eCO2 2000ppm) 臭いセンサーとしては使えそうだし、部屋が臭うという点においては換気の基準になるかもしれません。

次にやりたいこと

まぁ、換気の目安には使えそうもないのですが、せっかく買ったので次はRaspberyPiでデータをとって借りてるサーバーのデータベースに記録。 自分のホームページから前回作った温度モニターのような形で表示させられるようにはしようと思います。

↓温度湿度モニター作ったときの記事。 aki-lab.hatenadiary.com

とりあえず、問題なく動作確認はできました。