では最初に、(1)の「追跡」システムの作り方を説明します。
と、その前に、このシステムが実現するイメージを示します。ブラウザから、このサイトにアクセスして見てください。これは、本シリーズ第1回の父の「高速道路進入」事件を再現してみたものです。
もし、このシステムがあれば、父の高速の道路進入は止められていた ―― それは無理だったと思いますが ―― 過去60分間分くらいのトレースが残れば、未来の進路を、ある程度絞ることくらいのことはできたかもしれません。
それでは、構築方法を説明します。
(1)GPS受信キットの接続
(a)ラズパイと「秋月のGPS受信機キット」を、ジャンパー線を使って、以下のように接続して下さい。
(b)GPS受信キットを稼働させます
$ sudo raspi-config
「5 Interfacing Options」を選択→「 P6 Serial 」を選択し、「Would you like a login shell to be accessible over serial?」に対してYesを選択、Finishし、リブートします。
$ sudo reboot $ ls /dev/se*
で、/dev/serial0 ができている(はず)
(c)/boot/cmdline.txtの修正
既存の設定を#でコメントアウトした後、以下を追加して下さい。
dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait quiet splash plymouth.ignore-serial-consoles
ここでもう一度リブートします。
$ sudo reboot
その後、Pythonのシリアルモジュールをインストールします。
$ pip install pyserial
その後、
$ cat /dev/serial0
で、b'$GPGSV,4,4,14,23,05,150,19,14,04,054,*74\r\n' のようなメッセージが出てくれば、成功しています(結構な頻度で失敗しますので、覚悟してとりかかって下さい。Web等で調べて、自分の環境に合わせて動くようにして下さい)
(2)ディレクトリの作成
どこにどういう名前でもいいですが、ディレクトリを作ります。(ここではmaptest01としました)
cd ~; mkdir maptest01; cd maptest01
(3)位置情報取得プログラム(python言語)の作成
「秋月のGPS受信機キット」から得られた (ラズパイがある場所(自動車)の位置情報を捕捉し、その情報を、data.csvに書き込むプログラムです。nmea2csv_line.py という名前で保存して下さい。
# coding: UTF-8 import time, serial, micropyGPS, csv gps = micropyGPS.MicropyGPS(9, 'dd') def rungps(): s = serial.Serial('/dev/serial0', 9600, timeout = 10) s.readline() while True: sentence = s.readline().decode ('utf-8') if sentence[0] != '$': continue for x in sentence: gps.update(x) if gps.clean_sentences > 20: # データーが溜ったら出力 break now = time.ctime() cnvtime = time.strptime(now) print('id,title,address,latitude,longitude') print(',',end="") print(time.strftime("%H:%M,", cnvtime), end="") print (',%2.8f,%2.8f'% (gps.latitude [0], gps.longitude [0])) f = open('data.csv') # 1行スキップ line = f.readline() # 60分間分のデータ for num in range(60): line = f.readline() print(line, end="") f.close rungps()
これと、micropyGPS.pyというプログラムを、https://github.com/inmcm/micropyGPSあたりからダウンロードして、home/pi/maptest01の中にセーブしておいて下さい(行頭に、# coding: UTF-8 を付け加える必要があるかもしれません)
$ echo " id,title,address,latitude,longitude" > data.csv
として、data.csvを作った後、
$ python3 nmea2csv_line.py > tmp; cp tmp data.csv
を実行してみて下さい。
$ more data.csv id,title,address,latitude,longitude ,17:00,,35.216812, 137.133924 ,16:59,,35.221106, 137.133951 ,16:58,,35.228639, 137.137333
という感じで、data.csvファイルが1行増えていれば、成功しています。
さて、このプログラムを、自動的に1分間に1度だけ起動させるように、設定しておきます。
$ /etc/crontab
に以下を追記して下さい
*/1 * * * * pi python3 nmea2csv_line.py > tmp; cp tmp data.csv
(4)Webサーバプログラム(Go言語)の作成
以下のWebサーバプログラムを、main.goという名前で作成して下さい。
import ( "log" "net/http" ) func main() { http.Handle("/", http.FileServer(http.Dir("/home/pi/maptest01"))) if err := http.ListenAndServe(":8787", nil); err != nil { log.Fatal("ListenAndServe: ", err) } }
その後、go build main.go でビルドすると、main という実行ファイルができます。
これだけのプログラムで、Webブラウザから"http://211.158.177.150:8787"と入力すると、home/pi/maptest01にあるindex.htmlの内容が表示されるようになります(後述)。apache2やnginxのインストールも必要ありません。
さて、このWebサーバプログラムを、ラズパイ起動時に自動起動するようにしておきます。
/etc/systemd/system/maptest01.serviceという名前で、以下を保存して下さい。
[Unit] Description = maptest01 daemon [Service] ExecStart = /home/pi/maptest01/main Restart = always Type = simple [Install] WantedBy = multi-user.target
そして、
$ sudo systemctl enable maptest01
でエントリして下さい。
$ sudo systemctl start maptest01
とすることで、手動で起動を確認することができます。
(4)index.htmlの作成
今回は、GoogleMapではなく、Mapboxという地図サービスプラットフォームを利用して、地図上に、自動車の移動軌跡(マップピン)を、最大60本立てて、過去1時間の移動経路を表示します。
ちょっと話はズレますが「なぜ、私は、今回Mapboxを選んだか?」ですが、これは、私のGISシステムの師匠とあがめている方の以下の分析結果に従った結果です。
GIS界隈は、10年ほど見ている感じでは、登場人物は次のような感じです。
[商用]
[オープンソース]
国土地理院、OpenStreetMap、PostGISなど各種の確立されたプロダクトやデータ
-----
「無料」のため、やはりオープンソースが最大勢力です。こちらの地図情報については、今後も更新され続けていること、ノウハウの取得や維持更新の確実さから、さらに普及していくものと考えます。
最初に、Mapboxのトークンを入手して下さい(トークンが何のことか、分からなくてもいいです。とりあえず、必要なのは、あなた個人に付与される文字列です)。https://www.mapbox.com/にアクセスして、気前よく、個人情報をバカスカ入力して下さい。
すると、メールで、Mapboxを使うための、こんな感じの個人用のトークンが送られてきます。
pk.eyJ2IjoidG9tbXVycGh5IiwiYSI6ImNrNzF2b252NTA5czYzZW84ZTdnOWNmbjIifq._ezppDHNneEWX5BtYwAdzw
以下を、index.htmlとして保存して下さい。
<!DOCTYPE html> <html> <head> <meta charset=utf-8 /> <title>CSVファイルを地図に表示(mapbox)</title> <meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no\ ' /> <script src='https://api.tiles.mapbox.com/mapbox.js/v2.1.9/mapbox.js'></script> <link href='https://api.tiles.mapbox.com/mapbox.js/v2.1.9/mapbox.css' rel='styl\ esheet' /> <style> body { margin:0; padding:0; } #map { position:absolute; top:0; bottom:0; width:100%; } </style> </head> <body> <script src='https://api.tiles.mapbox.com/mapbox.js/plugins/leaflet-omnivore/v0\ .2.0/leaflet-omnivore.min.js'></script> <div id='map'></div> <script> // トークンはここで使う L.mapbox.accessToken = 'pk.eyJ1IjoidG9tbXVycGh5IiwiYSI6ImNrNzF2b252NTA5czYzZW84\ ZTdnOWNmbjIifQ._ezppDHNneEWX5btYwAdzw'; var map = L.mapbox.map('map', 'mapbox.streets') .setView([35.057686, 136.974811], 11); omnivore.csv('data.csv', null, L.mapbox.featureLayer()).addTo(map); </script> </body> </html>
この後、
$ sudo reboot
で、
Webブラウザから"http://211.158.177.150:8787"と入力
して下さい。取りあえず、現在時刻から、過去1時間分(60ポイント)の位置情報が表示されるはずです。また、リロード(または、Ctrl+F5)で、最新情報に更新されます ―― 運が良ければ。
なお、最初からうまく動くなんて、甘いこと考えてはいけません。あなたと私のラズパイは完全に同じモノではないからです。
システムというのは、原則「動かないもの」で、その後、ジタバタ、ドタバタを繰り返しながら、なんとかして「動かすもの」です。
Copyright © ITmedia, Inc. All Rights Reserved.