ラズパイを電源オンしたら自動的にGPSログを記録する (6)

 こんにちはドルフィンシステム福島です。
「ラズパイでモバイルセンシング端末を作る」の続きです。

前回は、ラズパイに接続したGPSから位置情報を取得する (5)でした。

具体的なステップ

  1. ラズパイ4にUSRP B200miniを接続する
  2. 電源は市販のモバイルバッテリーを使用することでコストを抑える
  3. 特定周波数のRSSIを計測しながら
  4. 接続したGPSの位置情報を取り込みロギングする
  5. ロギングしたRSSIと位置情報からマップを作成する

5段階の今日は前回に引き続き、4番のGPSログ取得を行います。

前回はログインしてgpsdやGPSログ記録コマンドを実行していましたが、ログアウトすると実行が終了してしまいます。

今後持ち運ぶことも考えると、電源投入したら自動的にGPSログ記録が行われる方が良いので、今回はその設定を行います。

gpsdの自動起動を設定する

前回はgpdsをコマンドラインで起動していましたが、今回はデーモンとして自動起動するように設定します。

まずgpsの接続ポートと起動時オプションを設定します。

$ sudo vi /etc/default/gpsd


gpsdを再起動してGPS情報を受信してみます。

$ sudo systemctl restart gpsd
$ gpsmon

OKですね。念のためLinuxを再起動してgpsmonコマンドで確認しておきましょう。

$ sudo reboot
~中略~
$ gpsmon


PythonでGPSログを取得する

前回まででgpsd(GPSデーモン)をインストールしてNMEA形式のGPSデータを取得することが出来ましたが、NMEA形式は使いにくい形式なのです。

例えばNMEA形式の移動経度は60進法で出力されますが、Google Map等で使われる座標は10進法なのでそのまま使うことが出来ず変換が必要になります。

という訳でPyhonでNMEAを受信しながら加工した情報を出力するようにします。

NMEA形式の文字列の例

$GPGGA,072739.437,5232.076,N,01322.994,E,1,12,1.0,0.0,M,0.0,M,,*67
$GPGSA,A,3,01,02,03,04,05,06,07,08,09,10,11,12,1.0,1.0,1.0*30
$GPRMC,072739.437,A,5232.076,N,01322.994,E,000.0,000.0,151120,000.0,W*75
$GPGGA,072740.437,5232.076,N,01322.994,E,1,12,1.0,0.0,M,0.0,M,,*69
$GPGSA,A,3,01,02,03,04,05,06,07,08,09,10,11,12,1.0,1.0,1.0*30
$GPRMC,072740.437,A,5232.076,N,01322.994,E,449.4,116.2,151120,000.0,W*72
$GPGGA,072741.437,5231.998,N,01323.154,E,1,12,1.0,0.0,M,0.0,M,,*67
$GPGSA,A,3,01,02,03,04,05,06,07,08,09,10,11,12,1.0,1.0,1.0*30

ちなみにNMEA形式で保存するためには、gpsmonコマンドで取得できます。

$ gpsmon -n -l log.txt


Pythonのモジュール類をインストールする

PythonでGPS情報を取り扱うgps3モジュールをインストールします。

$ sudo pip3 install gps3
$ sudo pip3 install python-daemon

ログを取る

以下のスクリプトを実行するとgpsdから取得した情報をCSVファイルに保存します。
/home/ubuntu/getgps.pyというファイル名で保存します。


from gps3 import gps3
import csv
import datetime
import dateutil.parser

gps_socket = gps3.GPSDSocket() data_stream = gps3.DataStream() gps_socket.connect() gps_socket.watch()

with open('/tmp/log.csv', 'w') as f:     writer = csv.writer(f, lineterminator='\n')     i=0     for new_data in gps_socket:         if new_data:             data_stream.unpack(new_data)             if(data_stream.TPV['time'] == 'n/a'):               continue             # ISO time to JST localtime             JST = datetime.timezone(datetime.timedelta(hours=+9), 'JST')             jst_timestamp = dateutil.parser.parse(data_stream.TPV['time']).astimezone(JST)             #print(jst_timestamp.isoformat())             list=[             i,             data_stream.TPV['mode'],             #data_stream.TPV['time'],             jst_timestamp.isoformat(),             data_stream.TPV['lat'],             data_stream.TPV['lon'],             data_stream.TPV['alt'],             data_stream.TPV['speed'],             data_stream.TPV['epx'],             data_stream.TPV['epy']             ]             print(list)             writer.writerow(list)             i=i+1

実行してみます。

$ python3 getgps.py


これなら1秒毎に時刻と緯度経度高度スピードが1行ずつ記録される分かりやすい形式になりました!


GPSログ取得をデーモン化する

以上で、GPSデータをロギングすることが出来るようになりましたが、Linuxからログアウトすると実行が停止してしまいます。

ログアウトしても動作が継続するようにするには、gpsgetスクリプト自体をデーモン化(サービス化)してしまいましょう。


gpsgetのUnit定義ファイルを作成してSystemdに登録する

$ sudo vi /etc/systemd/system/gpsget.service

[Unit]
Description = gpsget daemon


[Service]
ExecStart = /home/ubuntu/gpsget.py
Restart = always
Type = simple

[Install]
WantedBy = multi-user.target

gpsgetを有効にして開始する

$ sudo systemctl enable gpsget.service
$ sudo systemctl start gpsget.service


動作状況を確認する

$ sudo systemctl status gpsget.service

一度ログアウトしても生きています。

gpsgetを停止する

$ sudo systemctl stop gpsget.service


GPSの位置をGoogle mapで見てみる

取得したGPSの移動経度をGoogle Mapの検索バーに入力すると、その位置が表示されます。

見てみると。。。結構ズレてますね。
ログを見ると推定ズレが3.7m程ですが、10m以上はズレていそうです。


参考

https://tomosoft.jp/design/?p=41020
https://qiita.com/miminashi/items/563912092c9f593b8140#tpv
https://qiita.com/DQNEO/items/0b5d0bc5d3cf407cb7ff

まとめ

  • ログインして実行したコマンドはログアウトすると停止してしまう。
  • ラズパイ起動時に自動的にGPSデータを記録させるためにはデーモン化が必要。
  • NMEA形式は加工しないと使いづらい。
  • NMEA形式の移動経度は60進法で、Google Map等は10進法。

一つの測定システムを作り上げるためには、SDR以外の知識と経験がどっさり必要な事を改めて感じました。20年ほど前からLinux関連の仕事をしておりLinuxに抵抗はないので良かったですが、Linuxの経験値がないと組み上げるのが一苦労ですね。


コメント