2008 年 7 月 のアーカイブ

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

豊田おいでんまつりの花火をライブ配信してみた

昼に激しい雨降ってたし、色々準備不足で時間はないしで自転車を車に載せて現地に向かう。

この選択は結果からしてアウト。会場の豊田スタジアム周辺はヒドイ人手で、臨時の無料駐車場が軒並み満車。あいてる駐車場を探し回るだけで疲れる。車で来るんじゃなかったわ。

土手の上に場所取りして、花火始まると、目の前の道路標識がまるっきり花火とかぶることが判明。もっと入念に下調べするべきと反省。

花火大会のほうも、1万5千発も打ち上げているのにもかかわらず、最後までつかみ所がなくフィナーレであっけなく終了。こんなもんなんですかね?
近くで花火大会を見る経験って指を数えるほどしかないんだけど、洞爺湖の昭和新山火祭りが一番インパクトあって、感動した覚えがあります。

配信では、上りの帯域が足らないのか視聴者にキレイな映像が届けられなかったみたい。これからは現場で上り帯域をチェックしてから、ビットレートを決めるというプロセスが必要ですな。

来週は岡崎の花火に行く予定です。

千石電商から「プラグ」が届いたヨ

20080727  

以前のサイクリングで壊れた MyBatteryExpert n とXactiを繋ぐためのケーブルを強固なものでつくれないかという考えた結果がこれ。

MyBatteryExpert n の出力ジャックにあうプラグとXactiのDCアダプタにあうプラグが両端にあるケーブルを作っちゃえばいいじゃん。

ということで、千石電商にプラグやケーブルやらを諸々頼んだのが届いていたので、早速つくることにした。

20080727_2

  • MyBatteryExpert n は内径1.3、外形3.4でセンタープラス
  • Xactiは極性統一プラグ#2

    です。

    プラグの加工は上の画像の通り。
    まず、半田付けして、熱収縮チューブで絶縁と引っ張りの強化を図り、ホットボンドで固定と防水をするというやり過ぎも否めない作り方。
    久しく半田ごて握ってなかったけど、たまには工作も楽しいな。

20080727_3

ついでに、12Vの電池とEeePCのDCジャックにあう極性統一プラグ#3を使って、電池でACアダプタの代わりになるかを試してみる。

予想してたことだけど、電流が足りずに充電になったり内部バッテリーになったり、実際には使い物にならない。並列にすればokなのかも。

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

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

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

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

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

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

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

おお、これだ!

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

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

Webカメラの「Qcam Pro for Notebooks」が届いたヨ

<a href="http://eyevio.jp/movie/143856"><img src="https://i1.wp.com/eyevio.jp/_images/G/G6/G6ed3cbf4e376f79142ea648c75e345a/143856/leegbsjcqwedzyjjikdd_w1.jpg" data-recalc-dims="1" />20080725 GPS+車載テスト走行</a>

もう、Webカメラってもんじゃないんですね。そのままデジカメ・ビデオカムの代わりとして使ってもいい画質の精細さと、オートフォーカス・光量などの自動調節が素晴らしい。普通、暗いところでカメラ映そうとしても、映らないかISO感度が上がってノイズの乗ったひどい画質になるんだけど、このカメラは余裕で人間の目を同じように捉えてくれる。

こいつをQVGAで200kbpsという申し訳ないエンコードで使ってもったいないように感じるんだけど、動画の動きが激しくないときにコイツの本領が発揮されてるんで、よかったら動画でご確認ください。

今日は暑かったのでエアコン効いてる車で車載動画っていうのをテストとして撮ってみた。バックミラーにWebカメラのクリップを挟むだけで固定できちゃって楽チンすぎる。

一方でGPSのテスト。昨日の夜に作った、

  • GPSロガーからの情報をシリアル経由(Bluetoothをシリアルでエミュレート)でPythonでこしらえた実質5行くらいのプログラムでサーバにPOSTしてやり
  • サーバ側ではPOSTされたデータを単純に追加書き込みするPHPプログラム(どうせならPythonで作れよw)
  • 蓄積されたデータをGoogleMapsのPolyLineとMarkerに変換して表示するPHPプログラム(どうせなr)

を実際に動いて試す。

20080725

んで、思い通りのものが、簡単にできたのでオワリ。

1秒おきのデータはポイント数が大きくなりすぎるとか、自動で更新されないのがダサイとか、アイコンは自転車のアイコンにして進行方向に向いた形にしたい(API見たけど、回転のパラメータないから方向別に用意せなあかん)よねとか あるので、ちょっとずつ面白いものにしていきたいな。