‘GPS’ タグのついている投稿

初めてのジオキャッシングをやってみたよ

20080809

緯度経度で場所を指定され、その場所に行けばお宝がGETできるというゲーム、ジオキャッシングに挑戦してみた(+PeerCastで生中継)。

Yatsuomote mountain

西尾市の北東に位置する八ツ面山の山頂付近にあるキャッシュ。

20080809 西尾ジオキャッシング1 from Inagaki on Vimeo.
自転車で現場へ向かうまで

20080809 西尾ジオキャッシング2 from Inagaki on Vimeo.
八ツ面山でジオキャッシングをする!

The secret base of children

西尾市の市街にある西尾市歴史公園内のキャッシュ。

20080809 西尾ジオキャッシング3 from Inagaki on Vimeo.
八ツ面山のジオキャッシングの続きと歴史公園への移動(途中に寄ったコンビニでは編集をいれてます)

20080809 西尾ジオキャッシング4 from Inagaki on Vimeo.
歴史公園でジオキャッシング!

で。

残念ながら両方ともキャッシュの獲得ならず。本当に悔しい。

でも、経験したことのない・することのない機会を作ってくれるジオキャッシングというゲームは面白いね。西尾にこんなところがあったのかという発見だけでも、十分すぎるほどの収穫です。

次回やる場合は、スコップなどの掘る物・軍手・虫除けは必須。

さて、どこに行こうかな。

Pythonおもしろくなってきたかも

20080730

ぶっちゃけていうと、素のままではできることが少なく、最初からいろんな関数があたえられてるPHPと比べると大変なんだけど、シンプルさとソースの見やすさから好きになりそうな言語。わかりやすいし。

それで、GPSとのシリアル通信のプログラムなんだけど、
今まで readline() で読んでたところを、timeout値を1秒近辺(後述)にし read() で取ってやるとつまりもなく、非常にスムース

GPSからの出力データは1秒おきにどばっとくる。そこで、timeout値は0.9秒にしてやって、データがシンクロできるようにとPythonの計算時間を考慮して、一定のコンマ秒で read() する時間を逐次調節するように

ソースは以下の通り

#!/usr/bin/python

import sys, os, os.path, serial, urllib, urllib2, socket, thread, time

socket.setdefaulttimeout(10)

serialPort = 'COM6' #EeePC usb
#serialPort = 'COM3' #EeePC bluetooth
url = 'hogehoge'

tryCount = 0
baseTime = 0

def getGprmcSentence():
	global baseTime

	while True:
		try :
			buffer = ser.read(1000)
		except :
			print "error"
			return "error"

		if int(time.time()) + baseTime - time.time() > 0:
			time.sleep(int(time.time()) + baseTime - time.time() )

		if buffer[0:6] != '$GPGGA':
			print 'sync...'+"\n"
			time.sleep(0.1)
			if baseTime > 0.9:
				baseTime -= 0.9
			else:
				baseTime += 0.1

		if buffer[12:13] == '0':
			lines = buffer.split("\r\n")
			data = []

			for line in lines:
				nmea = line.split(',')

				if nmea[0] == '$GPGGA':
					if len(nmea) == 15 and nmea[14][0:1] == '*':
						data.append(nmea[9])
				elif nmea[0] == '$GPRMC':
					if len(nmea) == 13 and nmea[12][1:2] == '*':
						data.append(nmea[3])
						data.append(nmea[5])
						data.append(nmea[7])
						data.append(nmea[8])
						data.append(nmea[9])
						data.append(nmea[1])

			args = (data,)
			print "thread start..."
			thread.start_new_thread(putGpsData, args)

def putGpsData(args) :

	global tryCount

	params = {
	    "date" : args[5],
	    "time" : args[6],
	    "latitude" : args[1],
	    "longitude" : args[2],
	    "altitude" : args[0],
	    "speed" : args[3],
	    "heading" : args[4],
	}

	try:
		urllib2.urlopen(url, urllib.urlencode(params))
	except urllib2.HTTPError, e:
		print e

	tryCount = tryCount+1

	print tryCount
	print args
	print "\n"

def connect() :
	global ser, baseTime

	try:
		ser = serial.Serial(serialPort, 38400, bytesize=8, parity='N', stopbits=1, timeout=0.9, xonxoff=0, rtscts=0)
	except serial.SerialException, e:
		print e

	baseTime = time.time() - int(time.time());

	while True:
		temp = getGprmcSentence()
		if temp == "error":
			ser.close()
			return

	ser.close()

while True:
	connect()
	time.sleep(5)
	print "reconnect..."

んで、あとはGPSのデータから読み取ったデータにおいて10秒おきにスレッドでPUTしてやる。

そのPUTもhttpのタイムアウト値が10秒以上超してしまうと、整合性があわなくなるので、httpのタイムアウト値も10秒に設定

以前は、NMEAフォーマットのRMCセンテンスだけしかとってなかったので高度が取得できなかったけど、GGAセンテンスも読み取って高度をゲットや!

最後に、USBやBluetoothが途中に抜かれたり、通信エラーしても復帰できるように例外処理からsleep()かけて5秒後に復帰処理するように

PHPのほうは、Ajaxによる更新時間とGPSデータの更新時間が近すぎるとタイミングによってデータの2重取得や取得逃しが発生するので、GPSデータの更新時間から5秒後に更新する(実際にはサーバ時間で秒数の一桁が5秒のとき・・・サーバ時間が正しいことが前提だけどね)ように初回Ajax更新時間を調節

いろんなところにいって早く試したいなw

GPSロガーとのシリアル通信

pythonのシリアルモジュール使ってるんだけど、シリアルの入力をreadline()で取ってくると、1秒おきに10行程度の測位データを送ってくるのに間に合わずにバッファに溜まってしまうという現象が起きた。

面倒なんで、5秒おきにシリアルを受信しにいって、データが取れたら切断するというふうに改良したんだけど、今度はBluetoothでの通信やりとりがせいいっぱいみたいで、GPSロガー本体もオンオフ繰り返して、とっても苦しそう。

次に、POSTする処理をスレッドにすることでシリアル入力を楽にさせよう大作戦を行ったのだが、まったく無意味。

http://ymasuda.jp/python/pyserial/pyserial.html

ヒントを探すためにpySerialのREADMEを見ると、

flushInput() # 入力バッファをフラッシュ

おお、これだ!

今度はいい感じで5秒おきを守ってリアルタイムに動いてくれてる。

まず、最初にドキュメント見るってことを肝に銘じます。