Raspberry Pi 備忘録 / Mbedもあるよ!

Raspberry Pi であれこれやった事の記録

USB GPSデバイス GLOBALSAT BU-353S4 を試す

USB GPSバイス GLOBALSAT BU-353S4 を試します。

ソフトの準備

cu

$ sudo apt-get install cu

差し込んで、デバイスが認識されていることを確認

 $ lsusb | grep Prolific 
Bus 001 Device 006: ID 067b:2303 Prolific Technology, Inc. PL2303 Serial Port
$ ls /dev/ttyUSB*
/dev/ttyUSB0

conf ファイルを設定した。

# cat /etc/default/gpsd 
START_DAEMON="true"
USBAUTO="true"
DEVICES="/dev/ttyUSB0"
GPSD_OPTIONS="-F /var/run/gpsd.sock -b -n"

動作確認

# gpsmon
# xgps

オプション確認

GPSD
usage: gpsd [-b] [-n] [-N] [-D n] [-F sockfile] [-G] [-P pidfile] [-S port] [-h] device...
  Options include: 
  -b                        = bluetooth-safe: open data sources read-only
  -n                        = don't wait for client connects to poll GPS
  -N                        = don't go into background
  -F sockfile               = specify control socket location
  -G                        = make gpsd listen on INADDR_ANY
  -P pidfile                = set file to record process ID 
  -D integer (default 0)    = set debug level 
  -S integer (default 2947) = set port for daemon 
  -h                        = help message 
  -V                        = emit version and exit.
A device may be a local serial device for GPS input, or a URL in one 
of the following forms:
     tcp://host[:port]
     udp://host[:port]
     {dgpsip|ntrip}://[user:passwd@]host[:port][/stream]
     gpsd://host[:port][/device][?protocol]
in which case it specifies an input source for device, DGPS or ntrip data.

The following driver types are compiled into this gpsd instance:
                                NMEA0183
                                Ashtech
                                Delorme TripMate
                                Pre-2003 Delorme EarthMate
                                Furuno Electric GH-79L4
n                               Garmin NMEA
                c               MTK-3301
                                OceanServer OS5000
                                San Jose Navigation FV18
        b                       True North
                c               Jackson Labs Fury
                        *       AIVDM
n       b       c       *       EverMore
n                       *       Garmin Serial binary
                        *       Garmin USB binary
n       b               *       GeoStar
                        *       iTalk
                        *       Motorola Oncore
        b               *       Navcom
n       b               *       SiRF
n       b               *       SuperStarII
n       b               *       Trimble TSIP
n       b       c       *       u-blox
        b               *       Zodiac
                        *       NMEA2000
                        *       RTCM104V2
                        *       RTCM104V3
                        *       Garmin Simple Text
                        *       JSON slave driver
# n: mode switch, b: speed switch, c: rate switch, *: non-NMEA packet type.
# Socket export enabled.
# Shared memory export enabled.
# DBUS export enabled
# Time service features enabled.
# PPS enabled.

Python コーディング

gps を使うので、 インストールしておく。

$ sudo pip install gps

最初から入ってたかも?

こちらを参考にする。

Setting Everything Up | Adafruit Ultimate GPS on the Raspberry Pi | Adafruit Learning System

import gps

# Listen on port 2947 (gpsd) of localhost
session = gps.gps("localhost", "2947")
session.stream(gps.WATCH_ENABLE | gps.WATCH_NEWSTYLE)

while True:
    try:
        report = session.next()
                # Wait for a 'TPV' report and display the current time
                # To see all report data, uncomment the line below
        print report
        if report['class'] == 'TPV':
            if hasattr(report, 'time'):
                print "time:" + report.time
            if hasattr(report, 'speed'):
                print "speed:" + str(report.speed * gps.MPS_TO_KPH)
            if hasattr(report, 'lat'):
                print "lat:" + str(report.lat)
            if hasattr(report, 'lon'):
                print "lon:" + str(report.lon)
            if hasattr(report, 'alt'):
                print "alt:" + str(report.alt)
    except KeyError:
                pass
    except KeyboardInterrupt:
                quit()
    except StopIteration:
                session = None
                print "GPSD has terminated"

print report の箇所で、どんなデータが帰ってきているのか分かる。

こんな感じだ。(一部伏せました)

<dictwrapper: {u'epx': ***, u'epy': ***, u'epv': ***, u'ept': 0.005, u'lon': ***, u'eps': 63.47, u'epc': 187.7, u'lat': ***, u'tag': u'MID2', u'track': ***, u'mode': 3, u'time': u'2016-07-21T06:47:37.000Z', u'device': u'/dev/ttyUSB0', u'climb': -0.009, u'alt': 48.894, u'speed': 0.353, u'class': u'TPV'}>

ロギングの方針が決まっていませんが、とりあえず、緯度・経度・高度1セット出力したら修了するように改変する。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from datetime import datetime
import gps

# Listen on port 2947 (gpsd) of localhost
session = gps.gps("localhost", "2947")
session.stream(gps.WATCH_ENABLE | gps.WATCH_NEWSTYLE)

lat     = ''
lon     = ''
alt     = ''
tmie     = ''

while True:
        try:
                report = session.next()
                # print report # To see all report data, uncomment the line below
                if report['class'] == 'TPV':
                        if hasattr(report, 'lat'):
                                lat= str(report.lat)
                        if hasattr(report, 'lon'):
                                lon= str(report.lon)
                        if hasattr(report, 'alt'):
                                alt= str(report.alt)
                        if hasattr(report, 'time'):
                                alt= str(report.time)

                        if( lat!='' and lon!='' and alt!='' ):
                                print time
                                print "lat:" + lat
                                print "lon:" + lon
                                print "alt:" + alt
                                quit()
        except KeyError:
                pass
        except KeyboardInterrupt:
                quit()
        except StopIteration:
                session = None
                print "GPSD has terminated"

GPSログのフォーマットについて

どうやら、KML形式 と GPX形式 が、有名らしい。

gpxlogger という、そのまんまが有るので、利用する。

gpxlogger [-D debug-level] [-d] [-e export-method] [-f filename] [-l] [-m minmove] [-h] [-V]
                 [-i track timeout] [server [:port [:device]]]

   gpxlogger
       This program collects fixes from gpsd and logs them to standard output in GPX, an XML profile for track
       logging.

       The output may be composed of multiple tracks. A new track is created if there's no fix for an interval
       specified by the -i and defaulting to 5 seconds.

       The -d option tells gpxlogger to run as a daemon in background. It requires the -f option, which directs
       output to a specified logfile.

       The -m option sets a minimum move distance in meters (it may include a fractional decimal part). Motions
       shorter than this will not be logged.

       gpxlogger can use any of the export methods that gpsd supports. For a list of these methods, use the -l.
       To force the method, give the -e one of the colon-terminated method names from the -l table.

       If D-Bus support is available on the host, GPSD is configured to use it, and -e dbus is specified, this
       program listens to DBUS broadcasts from gpsd via org.gpsd.fix.

       With -e sockets, or if sockets is the method defaulted to, you may give a server-port-device
       specification as arguments.

どうやら、定期的にログを出すのではなく、設定した移動距離を超えたらログを出す仕様のようだ。

なるべく頻繁にロギングして欲しいので、、、

$ gpxlogger -d -i 30 -m 1 -f /usbmem/gps/`date +%Y%m%d%H%M%S`.gpx /dev/ttyUSB0

作成したファイルは、グーグルマイマップでインポート出来ます。

やってみたところ、起動直後のデータが 100m 程度ぶれており、あっちこっちにプロットされました。

NTP

Raspberry pi は、電池やバッテリが無く、OSが立ち上がっていない状態では時刻情報を更新しない。

そのため、起動すると、前回の時刻の続きに成る。

それでは困るので、GPSデータの時刻情報を元に、NTPで同期させる。

/etc/ntpd_conf

server 127.127.28.0 minpoll 4 maxpoll 4
fudge 127.127.28.0 refid GPS stratum 15

確認

$ ntpq -p
動作確認

数時間電源を落とした後に起動すると、同期してくれない。

man ntpd 抜粋

-g Normally, ntpd exits with a message to the system log if the offset exceeds the panic threshold,
which is 1000 s by default. This option allows the time to be set to any value without restric‐
tion; however, this can happen only once. If the threshold is exceeded after that, ntpd will exit
with a message to the system log. This option can be used with the -q and -x options.

1000秒以上のずれがあると、同期してくれない。

対応策としては、

$ sudo service ntp stop
$ sudo ntpd -qg
$ sudo service ntp start

となる。

が、足した所、1,2分待っても何も起こらなかった。

GPSDから読み取った値に対して、 date -s する方向で。