記事一覧

VSD for GPS に仮想光電管実装

ファイル 153-1.jpg

 先日公開した VSD for GPS,ありがたいことに既に何人かの人に使ってもらってるようだ.メーターとか走行軌跡表示とかは割りと反応がよさげだが,ラップタイム計測機能はいまいち不人気w たぶん計測方法がしょぼくて (全ラップでスタートラインを通過した瞬間を探し出してマークしなければならない),使い勝手が悪いんだろうな.

 というわけで,仮想光電管機能を実装した.これは,スタートラインの座標だけ与えてやれば,あとは GPS の位置情報からそこを通過した時刻を割り出して自動的に全ラップタイムを計測できる.まぁ GPS データロガーではメジャーな機能なんだけど,実装が大変なので先送りしていた.

 悩んだのは,AviUtl の GUI でどうスタートラインを座標指定するか.LAP+ の光電管ファイルをリードするのも考えたけど,LAP+ で作ってセーブして,また AviUtl でリードとかあまりいけてない.
 結局映像に一発だけマークを打つことでスタートライン位置を指定するようにした.これだとスタートラインの位置を映像で確認しながら仮想光電管を配置できるし.割と無理のない GUI にできたんじゃないかな.

 画像は,今回追加されたスタートラインの表示.微妙すぎて誰もきづかねぇよwww

車載動画スーパーインポーズフィルタを GPS に対応

ファイル 151-1.jpg

車載動画スーパーインポーズフィルタを GPS に対応中.

 今日は GPS ログ (NMEA-0183) を読み込んで車載動画と合成するところまで作りこんだ.といってもほとんどの部分は PSP GPS のときに実装しているので,新たに作るべきはログフォーマットの変更・スピードメーター表示・加速度計算くらい.

 で出かけついでにテストしてみたら以下の問題が見つかった.
・スピードメーターがプルプルするw
 生 GPS データはそんなに振動してないので,どうやら 5→30Hz にアップサンプリングするのに使用している Ferguson / Coons 曲線のアルゴリズムと GPS データの微妙な誤差の問題らしい.
 つうわけで当時苦労して仕込んだ当アルゴリズムは削除して単純な等比分割にしてみたけど,(GPS ログが 1Hz のデータでも) 大して差がなかったので,当初からいらんかったやんこれ.

・横 G がおかしい
 理論的には GPS のデータだけで前後左右加速度が求まるはずなので実装してみたけど,横 G のデータがおかしい.LAP+ では結構まともそうな横 G グラフが出せるので,算出方法を見直さないとな.
追記:と思ったら,360度のラップアラウンドが考慮もれしてただけだったw あと平滑化したら結構まともになった.


以下は残項目リスト
・最速ラップとのタイム差のリアルタイム表示
・仮想光電管の位置情報からラップタイムを自動計測

----
完成しました.欲しい人はここからどうぞ→VSD for GPS

MBM 高速起動

 フリーのブートローダーの MBM が久々にバージョンアップしていることに気が付いた.
 このバージョンアップで,MBM をインストールするドライブが選べるようになったのは便利.今まで C: にしかインストールできなかったので,USB メモリ等からブートすると (それが C: になってしまうので) HDD にインストールできなかったのだが,その制約がなくなった.

 今回から GPL になってソースコードも付属している.なので前からやりたかった「起動待ち時間を 1秒より速くする」(標準の MBM は自動起動までの最小時間が 1秒なので) をやるため,再アセンブルしようと思った.
 でやってみたら,アセンブラは OPTASM…? そんなのもう入手できねーよ(;´д⊂)ためしに MASM32 でアセンブルしてみたけどエラーの嵐.

 というわけで,方針を変えてパッチ当てで(笑) ソースは付属してるので,パッチ当て箇所がわかりやすくてありがたい.

1460  wait_timer:     ; 起動タイマー表示(CF=set on break, clr on time out)
1461          _skip e, MainParms.MpTime, 0
1462                   call   set_csrhome
1463                  mov     bp, 10 ←**ここ**
1464           _while
1465                  push    di

wait_timer で cx(=メニューで設定した待ち時間) * bp * 100ms 待っているので,bp への代入を 1にすれば,メニューで設定した秒数 / 10 の時間でタイムアウトする.(どうせ最小時間しか設定しないので問題なし)

バイナリ上のパッチ当て箇所は以下のとおり(ver.0.39).黄色で示した箇所を 0x0A→0x01 に書き換える.
ファイル 149-1.png
 これで MBM のメニューが一瞬でタイムアウトするようになったヽ(´ー`)ノ もちろんキーをあらかじめ押しておけばタイムアウトがキャンセルされるので,使い勝手的にも問題なし.

zlib にハマる

 とある Windows プログラムで,.gz 圧縮されたログファイル (テキスト) を直接読めるように,zlib を組み込んでみた.下がその一部

if(( fp = gzopen(( char *)szFileName, "r" )) == NULL ) return FALSE;
while( gzgets( fp, szBuf, BUF_SIZE ) != Z_NULL ){
    ....
}
gzclose( fp );

なんのことはない,fopen/fgets/fclose を gz なんちゃらに置き換えただけ.こんなん余裕っすよ.と思って実行してみたら,「invalid distances set」やら「invalid distance too far back」やらで全然リードできねぇ.たったこれだけのコードのどこに間違う余地があるのか_| ̄|○

 と,ふと目にとまったのが gzopen( ... , "r" ) の "r".Windows 上のテキストファイルだから何も考えずに "r" にしていたのだが,"rb" にしてみたら直ったヽ(´ー`)ノ "r" だと,0x0D 0x0A が 0x0A に変換されたりして .gz が壊れたのと同じ状態になってたんだろうな.
 てか,gz から解凍後のデータに対してテキストモードを適用すると思うでしょ普通.gz ファイル自体にテキストモードを適用してどうする (--# むか

Icarus Verilog vs. CVer

 ちょっくら,家で Verilog-HDL シミュレーションをやる必要が出てきたので,sim 環境を構築しようとしてみた.かつては Silos-III 評価版を魔改造してw 使っていたのだが,ちょっと大き目の回路だと落ちるようになってしまったので…
 フリーの Verilog-HDL シミュレータとしては,Icarus Verilog と cver が代表的だと思う.cver はどっかのベンダーが商用ツールをフリーとしてリリースしたもののようで,vcs とかになじんでいるとコマンドラインオプションとかが似ているので使いやすい.iverilog は 0.7 時代は使い物にならなかった印象かあるのだが,0.9 になって System Verilog とかにも対応したのか.すげぇな.

 で,SystemVerilg は使う予定がないので,普通の Verilog で,どっちが速いか試してみた.

お題: 16bit RISC CPU で 256個の数値クイックソート

GPLCVER_2.12a of 05/16/07 (Cygwin32).
9.108u 0.061s 0:10.27 89.1% 0+0k 0+0io 1607pf+0w

Icarus Verilog version 0.9.1 (v0_9_1)
37.327u 0.046s 0:40.57 92.0% 0+0k 0+0io 1842pf+0w

cver の圧勝.こんだけ差があると,iverilog を選ぶのはきついな.System Verilog を覚えてみるのもいいかとも思ってたのだが…(゜ーÅ)ほろり

----
 んー,ここの結果だと Icarus Verilog のほうがはやいなぁ.Cygwin 上でテストしたのが間違いだったんだろうか?
 てか,Verilator ってナニ!? VCS より速いフリーのシミュレータ!? おら,すっげぇわくわくしてきたぞwwww

AviSynth プラグインフィルタ自作(2)

ファイル 136-1.jpg

 ほぼ移植完了.AviUtl と AviSynth の差分は,画像データに点を打つ関数と,画像のプロパティ (縦横サイズとか) 取得部分のみなので割とすんなりと実装は済んだ.
 …と思ったら,MediaPlayerClassic で映像と音声とメーターがズレてるよ_| ̄|○ MediaPlayerClassic で動画のプロパティ見るとなぜか 25fps になってた.ffdshow のオンスリーンディスプレイでは 29.970fps になってるのに,いみがわからん.
 調べてみたら,.mp4 が 25fps になってしまうのは ffdshow のけっこう有名な問題らしい.そういや,AviUtl で ffdshow 経由で .MP4 開いたときもおかしくて,mp4input.aui 経由で読むように変えた過去があったし.でも ffdshow の新しいバージョンでは改善されたとかの記述もあるし,よくわからん.
 でとりあえず Haali Media Splitter 入れたら直ったヽ(´ー`)ノ そういや昔はこれ入れてた気もするが,ffdshow が新しくなってから入れなくても .mp4 見れるようになった(?) ので,入れてなかった.Haali Media Splitter 入れてない状態で,ffdshow 再インストしたら .mp4 見れなくなったので,何らかの .mp4 スプリッタが入ってたらしく,25fps 化はこの謎スプリッタが原因みたい.

 で,いろいろ使ってみたのだが,AviSynth 対応は自分ですら予想しなかったほど便利であること発覚.例えば 320*240 で撮影した動画は,640*480 に拡大してからメーターを重ねるなんてことが簡単にできるし,↓のようなスクリプトで 2つの車載動画を並べて同時再生とかもできるし.

c1 = DirectShowSource("SANY0001.MP4").ConvertToYUY2(). \
    VSDFilter( \
        "vsd20090123_095934.log", \
        video_start=8324, \
        video_end=68034, \
        log_start=4522, \
        log_end=34980, \
        map_length=240, \
        map_size=460, \
        map_angle=3406, \
        lap_time=1, \
        g_snake=1 \
    ). \
    BilinearResize( 320, 240 )

c2 = DirectShowSource("SANY0002.MP4").ConvertToYUY2(). \
    VSDFilter( \
        "vsd20090123_111455.log", \
        video_start=221, \
        video_end=52536, \
        log_start=8611, \
        log_end=35296, \
        map_length=240, \
        map_size=460, \
        map_angle=3406, \
        lap_time=1, \
        g_snake=1 \
    ). \
    BilinearResize( 320, 240 )

StackHorizontal(c1, c2)

こりゃ便利だわヽ(´ー`)ノ

AviSynth プラグインフィルタ自作

 車載動画スーパーインポーズフィルタ (vsd_filter) を,AviSynth プラグインフィルタに改造中.なんでそんなことしてるかというと,
・AviUtl で合成した動画は,.avi に書き出さなくても AviUtl で再生することはできるが,プレーヤーとしていけてないので,DirectShow 経由で普通のプレイヤーで見たい.
・Adobe Premiere とかで合成した動画を編集したいとき,いったん .avi に書き出さないといけない.AviSynth 経由なら,いちいち .avi に書き出さなくても直に読み込める
と,それなりに利点はあるので.かつて DScaler フィルタで作ろうと思ったけど,DScaler のプラグイン SDK は有料(?) みたいなので断念していた.
 というわけでここを見ながら AviSynth のプラグインフィルタについて勉強中.

移植に当たっての問題点は,
・AviUtl でダイアログで設定してるパラメータを,AviSynth では GUI で設定できない.なので,AviUtl の設定パラメータをファイルにライト・リードする機能を付加した.これで AviUtl の GUI でパラメータ調整→パラメータ書き出し→AviSynth のスクリプト内でパラメータファイルを指定,のようにすればパラメータを読み込めるはず.
・YUY2 のオペレーション.線とか円を書くとかの関数はクラス化してるので移植は容易で,これらの関数は最終的に 1ピクセルの点を打つ関数を呼んでいるので,アプリに依存しているのはこの 1ピクセルの点を打つ処理だけ.問題は YUY2 フォーマットでは U/V が横 2ピクセルで 1データを共有しているので,1ピクセルだけ打つというのが (画質を追求すると) めんどくさいよなぁ…

簡易ラップタイム計測機能だけ使用

ファイル 133-1.jpg

データロガーネタなんだけど,もはや PSP とは関係ないな…

めでたくカートでのヘルメットカメラ動画撮影に成功したので,これにラップタイムを合成表示させてみたくなった.ラップタイムのスーパーインポーズ機能自体はこのとき仕込んではあるのだが,あくまでも副次的な機能だったので,データロガーのログファイルを読み込まないとラップタイム計測機能は使えないようになっていた.

なので,さくっとメーター表示せずにラップタイム計測機能だけ使えるように改造.

ほしいひとはここからどうぞー.

stone を DD-WRT で動かす

 Linux サーバ (11b 無線 LAN で繋がっているので遅い) で動かしていた ssh サーバ + http プロキシサーバ を DD-WRT にやらせてみる計画発動.
 ssh はすでに動いているので,問題は proxy サーバ.すでにコンパイル済みの tiny proxy なるものがあるらしいが,色々と考えて DD-WRT で stone を動かしてみたくなった.

 というわけで,クロスコンパイル環境の構築から入る.最初は DD-WRT のクロスコンパイル環境を構築しようと思ったが,情報があまりないので断念.やりたいのは stone のクロスコンパイルだけだから,OpenWRT のクロスコンパイル環境でもいいのでは? ということで,楽なほうの OpenWRT の環境を構築.

http://downloads.openwrt.org/docs/buildroot-documentation.html
http://blog.gcd.org/archives/50849644.html
ここらへんの情報を元に Vine Linux 4.2 でやってみたら,make が古いだの autoconf の build に失敗しただの,わけがわからんので,CentOS の最新版を VMWare 上にインストールしてやっと構築できた.

 環境ができたところで stone のコンパイル.stone の Makefile にはすでに fon のコンパイルの設定があるので,それを参考に WNDR3300 用の make ターゲットを追加.

mipsel:
    $(MAKE) CC="mipsel-linux-uclibc-gcc" FLAGS="-O -Wall -DPTHREAD -DUNIX_DAEMON -DPRCTL $(FLAGS) -I/home/hoge/openwrt/staging_dir/mipsel/usr/include/" LIBS="-lpthread $(LIBS)" stone
    mipsel-linux-uclibc-strip stone

mipsel-pop:
    $(MAKE) CC="mipsel-linux-uclibc-gcc" TARGET=mipsel pop_stone

mipsel-ssl:
    $(MAKE) CC="mipsel-linux-uclibc-gcc" SSL_LIBS="-lssl -lcrypto -L/home/hoge/openwrt/staging_dir/mipsel/usr/lib" TARGET=mipsel ssl_stone

 基本的に s/fon/mipsel/g s/mips-/mipsel-/g しただけ.-I とか -L オプションはもっとスマートなやり方があるはずだが,よくわかんないので安易な方法で逃げた (^^; この状態で,

[mirage ~/stone]# set path = ( $path /home/hoge/openwrt/staging_dir/toolchain-mipsel_gcc3.4.6/bin/ )
[mirage ~/stone]# make mipsel
make CC="mipsel-linux-uclibc-gcc" FLAGS="-O -Wall -DPTHREAD -DUNIX_DAEMON -DPRCTL  -I/home/hoge/openwrt/staging_dir/mipsel/usr/include/" LIBS="-lpthread " stone
make[1]: Entering directory `/home/hoge/stone'
mipsel-linux-uclibc-gcc  -O -Wall -DPTHREAD -DUNIX_DAEMON -DPRCTL  -I/home/hoge/openwrt/staging_dir/mipsel/usr/include/ -o stone stone.c -lpthread
make[1]: Leaving directory `/home/hoge/stone'
mipsel-linux-uclibc-strip stone
[mirage ~/stone]#

 (文字にすると) あっさりとコンパイル完了.
 出来上がったバイナリを /jffs/ にほり込んでやると,WNDR3300 で無事動作したヽ(´ー`)ノ

車載動画スーパーインポーズフィルタをサーキットの友に対応

ファイル 109-1.pngファイル 109-2.jpg

自分はデータロガー環境を独自に構築しているが,これを他の人に広めようとしても,一番のネックになるのは車両からの情報を収集する方法.自分では H8 マイコンを用いているが,少なくともハンダ付けが必要なので他の人に展開するのはほぼ不可能だろう.

しかし世の中にはうまいことを考える人もいるようで,簡単なケーブルを自作するだけで,ノーパソが車両からの情報を収集できる機械になってしまうというものがあった↓
サーキットの友
原理としては,ライン (マイク) 入力に車両からの信号を突っ込んで,サウンドカードを AD 変換器代わりに使用して,CPU パワーでその波形をリアルタイムに解析すると.ステレオ入力だと最大 2ch (スピード・タコ) が解析できるから,簡易的なデータロガーになる.そういや同じような考えで,ライン入力をオシロスコープ代わりに使用するソフトもあったっけ.

もっと早くこれを知っていたら,自作データロガーとかわざわざ作らなかったかもw

で,サーキットの友 で車両のログを取ることはできるが,車載動画と合成する機能まではないので,自分の作った車載動画スーパーインポーズフィルタをサーキットの友対応にしてみた.

欲しい人はこちら

MAPLUS2 起動時間短縮計画

2chの下のカキコを見て,自分も title.pmf の置き換えやってみた.

836 名前:名無しさん@お腹いっぱい。 投稿日:2008/05/16(金) 04:58:04 nXzh70j2
ま、そうなんだよな
PSP側がGPSユニットを認識した時点で、捕捉開始するような仕様なら
意味があるのだろうが、どう考えてもデメリットの方がでかい。
ちなみに、title置き換えしただけで「○ボタン押せ」って警告画面までぶっ飛ぶから、
15秒近くの短縮にはなる。
けど、逆にいうと、GPSの捕捉完了にかかる時間が、
それくらいは必要だとEDIA側が考えてるって事だと思うんだよね。

上のカキコのとおり,起動時間早くしたところで GPS 捕捉時間が早くなるわけではないし,maplug 使ってるならどのみち放置するだけなので,別にやらなくてもいいのは分かってるのだが,EDIA が意地でもタイトル画面見せたいのなら,こっちは意地でも消し去ってやるってな感じ?w

で,上のカキコの「デメリット」とは ISO の再構築の手間がかかることをさしていると思うのだが,プラグインで sceIoOpen() を hook して,title.pmf が open されようとするときに別ファイルを open してやれば,プラグイン導入だけでファイルの置き換えができるので,手軽だろうと.
で,やってみた.

1. 0バイトの title.pmf
→最初の警告画面まで吹っ飛ぶが,その後のロード中 (右下に赤と白のバーがピロピロするやつ) が永遠続く
結果: 失敗

2. title.pmf を 64x64・12フレーム・無音・真っ黒 の dummy.pmf に置き換える
→dummy.pmf の再生は一瞬で終わり,その後 title2.pmf (犬とかが走り回ってる動画) が再生され,それの再生が 8秒間ほど終わらないと START が押せない
結果: 置き換え自体は成功だが,時間短縮になってない

3. title.pmf と title2.pmf を dummy.pmf に置き換える
→dummy.pmf が永遠に再生され,START が効かない
結果: 失敗

完敗っす(゜ーÅ)ほろり


気になるのは 2. の挙動で,title.pmf の再生時間が大体 8秒なのだが,2. では title2.pmf の再生が始まってるにもかかわらず START が 8秒後にしか効かないということは,.「pmf の再生」と「8秒待ってから START ボタンを認識する」が別スレッドになってるのかもしれない.

-----
ふと思ったが,例の追加ナビ音声をばらして MS に入れておいて,あるナビ音声を sceIoOpen されるのを hook して MS のナビ音声にすげ替えれば,面白い事態になるんじゃ…?

LuaPlayer バージョンアップ計画(2)

今日試してみて分かったこと

・System.loadPrx() は,ただ単に prx をロードして実行するだけ.prx 内のコードを Lua 側から呼び出したりできるわけではない.(何に使うんだ???)
・v0.20 では loadlib() が使えて,これがやりたいことそのものなんだけど,HM6.5 ではまだ使えないみたい.

というわけで,今のとこ GPS 機能を prx 化して LuaPlayerHM で使うことはできなさそう(゜ーÅ)ほろり

LuaPlayer バージョンアップ計画

 LuaPlayer が v0.20 からなかなかバージョンアップされないなー,と思ってたら,別のチーム? が作った LuaPlayerHM って言うほうに主流が移行していたのね.知らんかった.

 で,LuaPlayerHM だとFW3.x 系でも動く.ということは,usbgps.prx も同時に動かせるはず.でも今のところ,LuaPlayerHM のソースコードは公開されていないので,LuaPlayer に直接 GPS 関係のコードを埋め込むわけには行かない.System.loadPrx() で GPS モジュールをロードできるようにしたほうがいいだろうな.その方が他の人も使えてうれしいだろうし.

 てなわけで早速 LuaPlayerHM を導入して,(GPS のコードを殺した) データロガープログラムを実行させてみたら,「System.sioInit() は FW2.0 以下でないと動かないよ」と出て死んだ… 別に 3.x で sio が使えない理由は無いと思うのだが (実際やってるし).
まぁ,これもシリアル受信割込みを使用した prx 作って System.loadPrx() できるようにしたほうがいいだろう.
 余談だけど,Lua って組み込み済み function もユーザ定義 function でオーバーライドできるんだねぇ.例えば,

System.sioRead = function ()
    …独自コード…
end

とか.ユーザ定義 function 内で,loadPrx() したほうの sio 処理を呼び出すようにしとけば,今までの Lua コードはほとんど変更しなくて済むから便利.

とか考えつつ,GPS と シリアル通信関係を prx 化できるかどうか,検討中.
いつまでも CFW3.30 にしがみついてるわけにもいかないしね.

maplus_conv いぢり

maplus_conv を,ルート設定も変換できるように改造中.
もともと使い捨てツールのつもりだったので,GUI も無く,後の拡張も考えてなかったのでソースコードが汚ねぇ.改造でさらに汚く.

で,ルートデータのフォーマットは,favorite.dat とほぼ同じだろうと思っていたのが,実は違っていた.例えば,北緯/東経は unsigned int を 0x40000 とか 0x60000 とかで割れば実際の北緯/東経が得られたのだが,ルートのデータでは,0xE1000 で割らないとダメみたい.何でこんな値変えるのかね.てか,普通に float 型でいいじゃん… いや,float だと精度が不足気味か? もし精度向上のために固定小数点にしてるんだったら,0xE1000 じゃなくてもっと大きい値がとれるだろうに.

と,細かい事が氣になるサンデープログラマなのでした.

シフトアップインジケータ実装

久々の PSP データロガーネタ.

今のデータロガーには,LED によるデジタルメータとシフトアップインジケータ機能もついているんだけど,よく考えたら PSP にスピードも表示させてるし,もしかして LED ディスプレイいらねぇんじゃねえの? と思い始めた.

でも PSP のほうにシフトアップインジケータは実装されていなかった (構想はしていたけどズルズルと先送りに…) ので,これを期に実装してみた.
で,デモ動作を撮ってみたのが下の動画.(デモ動作は 0:46 あたりから.別の目的で作った動画なので,前半とかスル~でヨロ)

まあ見た目的には OK なんだけど,昼間でもシフトインジケータが点灯しているのに気づくほど輝度があるかどうか (真剣走りしてるときは PSP 注視する余裕ないので) と,データロガー本体からシリアル通信でデータを受け取ってる関係上タイムラグが発生するので,実際の Eg 回転数と表示とのズレがちょっと心配だな.

でも,もし LED を撤去する事ができたら,すっきりできていいかも.



なぁんて記事を書いてたら,今度のクラウンはメーターパネルがフルLCD!! もうちょっと早く出ると思ってたんだけどねぇ.しかしプロがデザインした LCD メータはカコイイヨ.俺のデザインセンスゼロメーターとはえらい違いだwww

DNSMasq で DHCP 登録されたホスト名から IP アドレスを解決させる

DNSMasq は,DNS 機能とともに DHCP サーバ機能も持っている.で,FON にインストールされていた DNSMasq では,DHCP により登録されたホスト名でも IP アドレスを解決できていたので,DHCP の特性上動的に IP アドレスが変わっても,ホスト名でアクセスできて便利だったのだが,Linux にインストールしたものは /etc/hosts しか見ない.

こんな機能もともと持ってるはずだよなぁと思ってオプションや conf ファイルを見てみたけど,それらしき設定がない.でもそれを間接的に実現できそうなオプションが見つかった.

具体的には,dnsmasq.conf 内の
dhcp-script=<コマンド>
で,DHCP にマシンが登録・削除されるたびにこのコマンドが呼び出される.そのときの DHCP アドレス貸し出し状況は (デフォルトで) /var/lib/misc/dnsmasq.leases に書かれているので,これを元に /etc/hosts を書き直した後,DNSMasq に /ets/hosts をリロードさせるために,kill -HUP すればよい.

というわけで,↓こんなスクリプトを書いて dhcp-script に指定してみた.

#!/usr/bin/perl -w

$Hosts = '/etc/hosts';
$Leases = '/var/lib/misc/dnsmasq.leases';

exit( 0 ) if( !( $ARGV[ 0 ] eq 'add' || $ARGV[ 0 ] eq 'del' ) 
    && -e $Hosts || ! -e $Leases );

open( fpIn, "< $Leases" );
open( fpOut, "> $Hosts" );

print fpOut << 'EOF';
# DO NOT EDIT THIS FILE
# This file is generated automatically by dhcp_update.pl
127.0.0.1       localhost localhost.localdomain

# これ以下~EOF の間に,固定 IP アドレスのホスト名を書く
192.168.0.254   ephemeris  dds_svr

EOF

while( <fpIn> ){
    @_ = split;
    print( fpOut "$_[2]\t$_[3]\t# $_[1]\n" ) if( $_[3] ne '*' );
}

close();

kill( HUP, `cat /var/run/dnsmasq.pid` );

/etc/hosts はこのスクリプトにより完全に上書きされる形になるので,DHCP 以外の固定的なホスト情報は,このスクリプト内に書いておかないといけない./etc/hosts に上書きするのがイヤなら,適当なファイルに吐いて dnsmasq.conf の addn-hosts= で指定する方法もあるが,そうすると DNSMasq が走ってるマシン自身で DHCP 登録されたホスト名でのアドレス解決ができない(???).

新しい PC が DHCP に登録されると,/var/log/messages に

Jan 20 17:22:46 ephemeris dnsmasq[1053]: read /etc/hosts - 4 addresses

とか出て,いちお期待通りに動いている模様.ヽ(´ー`)ノ

maplug 公開

このときに作った,MAPLUS2 のオープニングのキー入力を自動化するだけのプラグイン,公開しちゃったZE!

大した事ないプラグインなので,誰かが公開するだろうと思って様子をうかがってたら,実際誰かが 2ch に up したんだけど諸事情で取り下げちゃったみたい.なので,とりあえず少しでもお役に立てればと公開しました.相変わらず CFW3.71 には対応してないんだけどね.

ちなみに,EDIA がいぢわるしてるのか何なのか,MAPLUS1 では×連打で OK だったのに,MAPLUS2 では,しかるべきタイミングで○を押さないとだめ.普通は,一定時間待って○押すとかだろうけど,これだと UMD/ISO で押すべきタイミングが変わるし,ISO 起動にしても起動するごとに微妙に最適なタイミングは変わる.長めに待つというのは,なんかプログラマとして負けた氣がするのでw,ちょっとした工夫が入ってます.これで常に最短のタイミングでボタン押してるはず.

オービスアラームと GPS ログは撤去しちゃったので,もはや GPS 関数は hook してないので,gpshook ですらない (^^; ということで,MAPLUS の plugin ということで maplug という名前に改名.

でも,MAPLUS2 の GPS ログはなんか頻繁に途切れるんだよなぁ… もしかしたら GPS ログ機能は復活させるかもしれない.

PSP GPSウォームスタート成功

コールドスタートになっていると思われる PSP データロガーの GPS,10分たっても捕捉開始しねぇ,という事で,ウォームスタートを実装.

コード自体は,いつもお世話になってる Deniska 氏のとこの PSP-290 テストプログラムを見ると,sceUsbGpsSetInitDataLocation( int ) というのが使われているので,これだろうという事で LuaPlayer に実装.問題は引数で,0 〜 2 の値を指定するらしい.おそらく,ウォームスタートのためのデータ保存スロットが 3箇所分あり,そのどれかを GPS ユニットにロードするのだろう.MAPLUS がどのスロット使ってるかは分からないが,とりあえず 0 を指定しておいた.

で,MAPLUS で位置を測位するまでほっとく→電源 OFF→データロガープログラム起動! で,3分後くらいに見たら,おお! 捕捉開始してるではないかヽ(´ー`)ノ どうやらsceUsbGpsSetInitDataLocation( 0 ) は正解だったようだ.

車載動画への自車位置表示も実装したことだし,これでやっと実用になるな.

車載動画スーパーインポーズフィルタをアップデート


車載動画スーパーインポーズフィルタを大幅アップデートしてみた.

■コースマップ
 ついにコース上の自車位置表示を実装.前回のフリー走行でコース上での GPS ログ取りに失敗したので,上の動画では鈴鹿スカイラインを走ったときのログを無理やり貼り付けてみたが,結構いい感じ.一秒毎の位置計測データを 30ポイントに補完する処理もうまくいっているようだ.

■最速ラップとのタイム差表示
 何か走行分析に有用な情報を表示させようとしてみたのがこれ.データロガーには走行距離も記録されているので,各周の同一走行距離における経過時間がわかるので,最速ラップとのタイム差がわかる.
 実装してみると,意外とまとも.データは距離メーターが全てなので,タイヤが空転したり最速ラップと大幅に違うラインを大回りしたとかなると怪しくなるが,動画を見ながら今のライン取りはうまくいったんだなとか,けっこう新発見があった.

■640x480 の見栄えを改善
 今まで 320x240 でのエンコードを前提としたメーター描画だったので,フォントサイズが小さいとか,ラインが細すぎとか,見栄えがよくなかったが,640x480 でのエンコードを前提とした見栄えの改善をしてみた.
 後,メーターの配色や,ラップタイム表示を縁取り文字にして背景の白をやめてみた.


んー,満足ヽ(´ー`)ノ
これで画像合成フィルタでやりたい事はほぼ終わったかな.

データロガー+GPS (PSP部分だけ)完成

ファイル img_26537677_0.png

データロガーのログ取りプログラム ( LuaPlayer のスクリプト ) に,GPS ログ取り機能を追加してみた.ってこれ前もやったよなぁ.データロガー + GPS 計画を一旦中止したので,そんときにコードを消しちゃったんだっけ(゜ーÅ)ほろり

まぁ気を取り直して再コーディング.GPS のデータに関しては,PSP で表示するものはあまりなくログに記録するだけなので,結構楽.とっとと完成させて,給油がてらログを取ってみた.

が,GPS と関係ない問題が一つ.Lua の os_date で日付を取得すると 1970/1/1 になってしまう.os_date の部分のソースコードを見ると,localtime() で日付を取得していたので,sceRtcGetCurrentClockLocalTime() に書き換えたら,正常に取得できた.でもなんで? localtime() も追っていけばたぶん sceRtcGetCurrentClockLocalTime() に行き着くと思うのだが…???

これで,後は車載動画と合成するプログラムを残すのみとなったが,めんどくさそうw

LuaPlayer+シリアル通信復活!!

LuaPlayer@3.xx カーネル のシリアル通信が復活!

3.xx カーネルではシリアル通信が出来ないのかとあきらめていたところ,新型 PSP ですでにシリアル通信が動いているとの情報を頂き,それを組み込んでみた.…だが,やっぱり動かない.んー残念!! こうなりゃ意地だと,いろいろ解析してみると奇妙な事が分かった.

シリアル通信のルーチンでは,「シリアルデータを受信してバッファに書き込む割り込みルーチン」と,「バッファから 1バイト読み出すスレッド」から成り立っており,割り込みルーチンと読み出しスレッドは変数を介して通信するのだが,割り込みルーチンが書き込んだ値を読み出しスレッドで読めないという事に気づいた (無論変数は volatile 指定している).さらに解析を進めたところ,大きい配列を介すると,変数を介した通信が成功する.

何でだ?? と思って,C コードをアセンブラに落としてみた.

上手くいかないほうのコード:

lw $3,%gp_rel(uRxBufWp)($28)


これは,uRxBufWp という変数の値を,レジスタ $3 にロードしているところだが,怪しいのが %gp_rel(...)($28) で,$28 からの相対アドレスでロードする事によって,命令数を少なくしている.$28 はおそらくスレッド開始時に初期化されて,その後変更されないのだろう.

一方上手くいくほうのコード:

lui   $2,%hi(cRxBufWp)     ; $2 = (cRxBufWp のアドレス値の上位)
addiu $2,$2,%lo(cRxBufWp) ; $2 += (cRxBufWp のアドレス値の下位)
lw $4,0($2) ; $4 = [$2], すなわち $4 には変数 cRxBufWp の値が入る


このように,$28 の相対アドレスではなく,$2 に直接 cRxBufWp のアドレス値を代入してから,$4 に cRxBufWp の値をロードしている.

以上の事から推測すると,スレッドごとに $28 の値が異ることがあり,C 言語上では同一の変数を指定していても,異なるスレッド同士では実際のアドレスは異なる事がありうる?

でもこんな仕様ありえねー.コレってコンパイラか BIOS か,なんかのバグだよなぁ.

-----

で,シリアル通信のほうは,けっきょく元々のソースコードの,通信に使用していた変数をちょこっと変更するだけで,無事動いたヽ(´ー`)ノ

というわけで,データロガー + GPS 計画復活!!

LuaPlayer+シリアル割り込みコネ━━━━(゜A゜)━━━━ッ!!

LuaPlayer + USBGPS,点を曲線で結ぶアルゴリズムの習得,と,走行動画に走行軌跡を合成する計画は着々と進行中.今日は,PSP の画面表示+ログ プログラムに GPS ログも記録する機能を追加して,データロガーと接続してテストしてみた.

…シリアル通信ができない_| ̄|○

3.xx カーネルモードの LuaPlayer が悪さしてるのか? と思って 1.50 カーネルの LuaPlayer で動かしてみたら,(当然 GPS は使えないものの) シリアル通信は出来た.

3.xx カーネルの LuaPlayer,シリアル割り込みが出来てないじゃん_| ̄|○
シリアル割り込みのソースコードは,どっかから持ってきたやつなので,自分ではどうしようもない.更にシリアル割り込みとかやってる人なんか他にいなさそうなので,3.xx で動く記述とかどこ探してもないだろうなぁ…

これにて,データロガーに GPS ログも記録する計画は中止(゜ーÅ)ほろり

LuaPlayer+GPSキタ━━━━(゜∀゜)━━━━ッ!!

ファイル 21-1.jpg

ついに LuaPlayer で USBGPS キタ━━━━(゜∀゜)━━━━ッ!!

なににハマってたかって,
・カーネルモードの EBOOT.PBP は BIOS1.50 以下でないと動かない.(3.30OE-B とかでは GAME150/ の下に置かないと動かない)
・usbacc.prx / usbgps.prx は BIOS3.xx でないと動かない (GAME150/ の下に置く EBOOT.PBP ではロードできない)

らしいという事が試行錯誤の末見えてきたんだけど,元々のオリジナルの LuaPlayer の構成が,

GAME150/ の下:
EBOOT.PBP (カーネル)
+-loadlib.prx (カーネル)
+-luaplayer.prx (ユーザ)


になってて,単に usbacc.prx/usbgps.prx をロードするように改造しても,↓

GAME150/ の下:
EBOOT.PBP (カーネル)
+-loadlib.prx (カーネル)
+-luaplayer.prx (ユーザ)
 +-usbacc.prx ←sceKernelLoadModule() 失敗
 +-usbgps.prx ←sceKernelLoadModule() 失敗


BIOS1.50 では usbacc.prx/usbgps.prx のロードで死亡,

EBOOT を BIOS3.xx で起動しようとしても↓

GAME/ の下:
EBOOT.PBP (カーネル) ←XMB から起動できない
+-loadlib.prx (カーネル)
+-luaplayer.prx (ユーザ)
 +-usbacc.prx
 +-usbgps.prx


という板ばさみになって,ぜんぜん前に進まなかったわけ.

そこで LuaPlayer を以下のように大改造してみた.↓

GAME/ の下:
EBOOT.PBP (ユーザ)
+-luakernel.prx (カーネル) ←元々の EBOOT の機能を prx 化したもの
+-loadlib.prx (カーネル) ←現状,sceKernelLoadModule() 失敗
+-luaplayer.prx (ユーザ)
+-usbacc.prx
+-usbgps.prx


これがビンゴ!! とりあえず USB GPS の機能は一通り使えて,無事 LuaPlayer で現在位置を取得する事が出来た.ヽ(´ー`)ノ (写真のモザイクかかってるところが,現在座標ね)

現状,loadlib.prx がロードできない (3.xx ではカーネルモードの prx の制限が厳しくなったので,luakernel.prx もロードできるようになるまで苦労したよ(゜ーÅ)ほろり),USB DISK モードが使用できない等いろいろ制限もあるが,ま,目的の「データロガーに GPS で取得した位地データも記録する」には支障がなさそうなので,よしとするか.

GPSが動かないよ〜♪

何回やっても何回やっても GPSが動かないよ〜
あの prx 何回やっても読み込めない♪ (字余り)


歌いたくなるくらい,依然 LuaPlayer + USBGPS が動かない.どうやっても sceKernelLoadModule( "usbacc.prx", … ) が死ぬ… 前回は,このコードを EBOOT.PBP でやれば動くと思っていたが勘違いだったようだ.

PSP-290 のテストコードはコンパイル→実行がちゃんと動くので,差分を追っていったら,テストコードはカーネル 3.02 モード(???) でコンパイルしている模様.要するにカーネル 1.50 モード (make kxploit) じゃないほうの make でコンパイルしてある.って,これってカーネル 1.0 モードじゃないの? LuaPlayer を 3.02 モードでコンパイルってどうやるんだろ…?

でも考えてみりゃ,USB GPS はカーネル 1.5 には無かった機能だから,1.5 モードでコンパイルした sceKernelLoadModule( "usbacc.prx", … ) が死ぬのはなんとなく説得力があるような… (そもそも usbacc.prx/usbgps.prx が 3.x から引っこ抜いてきたやつだし)

カーネルモード/ユーザーモードとかも絡んでるみたいだし,

もうよくわかんねぇよヽ(`Д´)/ウワアアン

LuaPlayer + GPS

長い間ほうっておいた,LuaPlayer で GPS を駆動する,を再開.けっきょく GPS の位置情報は最短で 1秒ごとにしか更新されないので,データロガーの情報としては使い物にならないが,まぁ車載ビデオに現在位置をプロットしてみるのも面白いかも,と思ってね.

前回までに PSP-GPS テストコードを参考に,UsbGps の prx ロードとか,初期化コードとかの組み込みは終わっているのだが,どうやら usbgps の prx の sceKernelLoadModule() で死んでいる模様.…何で? (゜ーÅ)ほろり

ちなみに,LuaPlayer は,ブートプログラム ( EBOOT.PBP ) と LuaPlayer の本体 .prx とに分かれているので,sceKernelLoadModule() を EBOOT.PBP のほうに移動したら,sceKernelLoadModule() 自体は成功している模様.ただし,その他の初期化コード (本体 prx の方にある) が失敗する.

んー,初期化コードも EBOOT の方に移動せにゃならんのか? でもそうしてしまうと,GPS 使う / 使わないにかかわらず,LuaPlayer 起動するだけで GPS が動き出してしまう.それは気持ち悪い.理想は lua のスクリプトで GPS 初期化ルーチンを呼んで初めて GPS が動き出す,てな動きだが.

んー,いろいろややこしいね.

予想通りのオチがつきました

 PSP-GPS がデータロガーに使えるかどうか調べてみる.データロガーとして使うには,最低でも 10Hz の更新頻度がないとダメだろう.で LuaPlayer を改造する前に,「そういや PSP-290 のテストプログラムを誰かが公開してたよなぁ」というのを思い出して,さくっとダウンロード & 実行.

 念のため,GPS テストプログラムの GPS データリード間隔を 100ms に改造してみたが,データの更新頻度は 1秒間隔でした.要するに 10回は同じ位置情報しか読み出せない.あーーーーー,やっぱダメか_| ̄|○

とりあえず GPS でラップタイム測る計画はおじゃんだなぁ.いや,欠けた位置情報を車速パルスや Gセンサーで補間できるか? でも精度が…

mp3prx+gpshook

 んー,最近ネタがなくなったので,PSP プログラミングに手をつけれていない.

 まぁ,データロガーを通して車速パルスと Gセンサーの値を PSP に取り込む事はできるので,MAPLUSで GPS 衛星をロストしたときに,コレを使って自律航行しようというネタはあるのだが,やる気がでねー.

 で,モチベーション維持のため,mp3prx と gpshook を合体させてみようと.こうするとサウンド再生ルーチンのみならず,メインスレッド・コンフィグ読み込み・キーセンス・画面上へのメッセージ出力の処理が共有できるので結構メリットが大きい.しかもくっつけるだけなら 1時間くらいでできるだろー
と思って軽い気持ちではじめたら,そうは問屋がおろしませんでした_| ̄|○

psp-fixup-imports irsmp3.elf
Error, could not fixup imports, stubs out of order.
Ensure the SDK libraries are linked in last to correct this error
make: *** [irsmp3.elf] Error 1


なにこれ.こんなメッセージみたことねぇ!!! ググってダメなら,もうお手上げヽ(´ー`)ノ

ちなみに,ウチの地域ではカーグラ TV 放送されてませんw

コードを1byte小さくする事に命を賭ける

 DOS とかで,config.sys をいじって○○を UMB にロードしたりとか,メインメモリの空きを 1バイトでも多くする事に命をかけてた事ってあったじゃん? アセンブラでも自己可変コードとか使ってクロック数単位で実行速度を上げたりとかしたよね.あ,俺だけ? はいはい,どうせあたしゃ変ですよ.

 で,めでたく CFW3.30OE-A' に対応できた gpshook だが,どうもメモリがきついらしい.いや,単体だとまだ余裕ありげなんだけど,mp3prx がでかい (俺的にはこれははずせない) ので,もうぎりぎりっぽい.なので,gpshook.prx のサイズを小さくしようと,かつてのメモリ節約魂が復活したわけ.

 で,いろいろ試して面白かったのは,整数/浮動少数演算が混在している箇所で,コードサイズが結構変わる.

例1)
int_a = int_val + float_val * 100;
-----
int_a = int_val + ( int )float_val * 100;

こりゃ当たり前レベルなので分かりやすい.浮動小数点演算を行う範囲が減ってるもんね.

例2)
unsigned int uint_val = float_val;
-----
unsigned int uint_val = ( int )float_val;

float_val が正数しかとらない場合,結果はどちらも同じだが,なんとこれもコードサイズが違う.
上のほうでは,なんか符号をいろいろいじるコードが余計についていた.

例3)
int int_val = int_val2 % 360;
-----
unsigned uint_val = uint_val2 % 360;
これも差がないと思ってたら,下のほうが小さかった.

とにかく,変数が signed か unsigned かだけでも 数10バイトの差が出てくる.
(あくまでも psp-gcc (MIPSコンパイラ) の場合だが)
たまには gcc が吐いたアセンブラを眺めるのもいいなぁとおもった.え,そんなことないって? はいはい,どうせあたしゃ変ですよ.

てか,gpshook.prx でちまちま削るより,mp3prx をいじったほうがザクっと削れそうだということに今氣が付いた.

PSP サスペンド/レジューム後の ファイルハンドル [解決]

ファイル 44-1.png

 gpshook.prx のログファイル破壊がやっと解決した.長かった…
 結論から言うと,ちゃんと scePowerRegisterCallback は効いていたみたい.ただ,それのコールバック関数内でファイルディスクリプタを sceIoClose すると,なぜか死ぬとか,レジューム後にコールバック登録が無効になってるとか,いろいろわけの分からん現象がわんさかと_| ̄|○
 この辺はドキュメントにも動作が記載されてないので,トライ & エラーで試すしかない.で,苦労しながらも一応うまくいったわけだが,これで合っている確証もないがもういじりたくないのでこれでよしとしようwww

BIOS 3.30 OE-A で動かないとかのうわさもあるが,自分は FW アップデートする気がないので別にいいや(笑) これにて gpshook.prx の開発は終了っと.

PSP サスペンド/レジューム後の ファイルハンドル

 ほぼ完成したはずの gpshook.prx だが,重大な問題がある事発覚.
 ログ取り中に PSP をサスペンドすると,ログファイル (の残骸) が,破損クラスタになってしまう.すなわちログが失われてしまう.これは痛い.PSP をサスペンドすると,open 中のファイルハンドルがクローズされるのは結構有名な問題らしいのだが,write モードで開かれたファイルを中途半端に close してくれやがる(;´д⊂)

 いちおう,サスペンドに入ろうとするときにそれを検出する手段 (scePowerRegisterCallback) はあるのだが,プラグインでこの API を使ってみても,うんともすんとも検出してくれないです…
 おそらく,MAPLUS が scePowerRegisterCallback して,gpshook.prx が scePowerRegisterCallback したのが解除されているのかな?

( ̄-  ̄ ) ンー どうしたものか.


ページ移動