2017年1月17日火曜日

HIGH SCHOOL FLEET FAN BOOK

はいふりファンブック、やっと届いて、やっと読めた。いやー、良かった。

アニメの設定資料としてだけでなく、当時(WWII)の船を動かすためにどういう事が必用かとかの説明もあったりと、そういうあたりの資料としてもいいと思います。WWIIの船に興味あるけどいきなり軍事解説書は…みたいな層にも。やんわりと読めるので。

さんざん色んな所で書かれてるけど、やっぱ劇場版とかやってほしい。アニメの中でも出せてないシーンだって有るし、過去や未来に渡って様々なエピソードがありそうなので、そのあたりも含めていろいろな展開ができそう。


話の感じとしては、ミニスカ宇宙海賊(原作のラノベの方)に近いと思う。ヨット部と海賊の連携みたいなああいうノリでみんなでいろいろやってほしい。


春風クラスをインディペンデンス級に載せて機雷掃海手順を説明した同人誌とかも面白そう。ALMDSとかも飛行船に載せたりいろいろできるだろうし。


とかいろいろ妄想が広がりつつ。


2017年1月16日月曜日

SDR#で複数の周波数を同時に受信する

次はイリジウムだと言ったな。あれは嘘だ。もうTLEも出てるんですけどね。それぞれの名前が出てからにしようと思っています。

それとSS-520残念でしたねぇ。TRICOMのミッションは期待していたし、軌道を見るのも楽しみにしていたんですが。ISS放出とかでぜひやってほしいものです。ロケット側も、シリーズ化はしないと言っていましたが、実験的な挑戦はやめるみたいな風潮にならないようにしてほしいものです。

***

さて、本題。
せっかくのソフトウェアレシーバなので複数の周波数を同時に受信したい、ということで試してみた。SDR#を使ってあれこれやってみたが、「不可能ではないが実用的ではない」という感じ。もっとオフィシャルな方法で簡単にできるかもしれないが。


左下のExcelにおおよその設定を書いたが、まず1つ目のSDR#がハードウェアアクセスを担当する。残り2つのSDR#がそれぞれの周波数の復調を担当する。

SDR#のRAWはバンド幅が32kHzまでしか設定できないから、範囲に入る帯域しか受信できない。例えばFMラジオ放送は35kHzくらいの帯域幅が有るから、ギリギリ受信できないことはないが、音質は悪いし実用性もない。そもそも1chしか受信できなくなるからやる意味がない。

とりあえずアナログ特小トランシーバを2ch同時に受信することはできてるが、これが実用的かというとそんなことは全く無い。2chだけなら安いトランシーバを2台並べるほうが楽だし、ハイゲインアンテナを使いたいなら適当なワイドバンドレシーバでも並べたほうが良い。そっちのほうが使いまわしが効くし、自由度も高い。
ということで、実用性は全く無い。

ノンリアルタイムでかまわないなら1MspsでIQを保存して、あとからそれぞれのチャンネルで復調&音声に保存してミキサーに突っ込めばいい。もっとも、SDR#は32bitアプリなので2GBに制限されるから、あまり長い時間は受信できないが。はやく64bitビルド作ってくれ。


ということで、リアルタイムに複数チャンネル受信したいなら、必用なチャンネル分の広帯域受信機かワンセグチューナを買う必要がありそう。

せっかくのソフトウェア無線なんだから、アナログ特小20ch同時待機とか、いろいろできたら楽しいと思うんだけどねぇ。

2017年1月15日日曜日

メモ:C#で2GB以上のメモリ

* 追記:2017/01/17
あとで読み返したら数字とかいろいろおかしいね。やっぱ夜中に文章とか書くもんじゃない。以下参考程度に。
* ここまで


64bitビルドで、例えば構造体配列とかで全体が2GBを超えたい時に使うオプション。

<gcAllowVeryLargeObjects> Element

hoge.exe.configでconfiguration > runtimeにgcAllowVeryLargeObjects enabled="true"を追加する。

ただあんまり使い勝手は良くない気がする。


このオプションを追加した状態では、配列の最大長はUInt32.MaxValue(0x7FEFFFFF)まで、ただし任意の単一次元の最大は0x7FFFFFC7か0x7FEFFFFFに制限される、となる。
つまり、1次元配列の場合は0x7FFFFFC7くらいまで、多次元配列ならすべての要素数がUInt32.MaxValue未満まで、ということになるらしい。

例えば、new int[0x7FEFFFFF/2, 4]という配列は合計長が0xFFDFFFFCでMaxValueを下回っているために作成できるが、new int[0x7FEFFFFF/2, 5]だと合計長が0x13FD7FFFBとなり、作成することができない。

new int[UInt32.MaxValue]という配列を作ることはできない。これは「任意の単一次元は0x7FFFFFC7か0x7FEFFFFFに制限される」という点に引っかかるため。


この合計数は多次元配列にのみ課される制約であり、ジャグ配列には適用されない(多次元配列は[2,3]のタイプ、ジャグ配列は[2][3]のタイプ)。
int[][] arr = new int[0x7FEFFFFF][4];のような大きさだと合計は0x1FFBFFFFCになるが、問題なく作成できる。


前述のとおり、制限になるのは添字だけであり、配列を用意するためのメモリに制限はない。多次元配列ではUInt32.MaxValueが1つの制限となるが、ジャグ配列を使えば回避することができるし、構造体の配列であれば事実上無制限に大きなテーブルを作ることもできる。
とはいえ、実際に使用できるのはPCに実装してある容量の半分前後が目安となる。
僕のデスクトップPCは32GBのメモリを載せているが、使用するメモリが20GBを超えたあたりで実メモリのデータを仮想メモリ(ハードディスク)へ退避し始め、OSのパフォーマンスが極めて低下した。これはブラウザのスクロールがカクつくというレベルではなく、マウスを動かすこともできないレベルのパフォーマンス低下を引き起こす。


ということで、64bitOSで20GBくらいのメモリを専有するプログラムを作る方法はわかった。が、本来の目的である超高解像度Bitmapは結局無理っぽい感じ。いろいろ数字をこねくり回すと前述の数字に近いところが出てくるが、なんか腑に落ちない。とりあえずSystem.Drawing.Bitmapでは前回のエントリで書いた解像度の制限が消えることはないはず。

***

標高データのタイルを貼り合わせるのもだいたいやり尽くした感があるし、そろそろ違う何かで遊びたいなー。何ヶ月単位でやってない電子工作を久しぶりにやりたいところだけど、それには机の周り片付けるところから始めないといけないから、なかなか腰が上がらない。入手性が良くて安くてバカでも使える簡単なArduino非互換な.NetMFボードとかどっかにないかなー。


/*
気が付かなかったけど、これ書いてる途中にFalcon-9の打ち上げがあったのね。惜しいことしたなー。数日中に軌道要素が出ると思うので、次のネタは10機まとめて打ち上げられたイリジウムとTRICOMのTLEを貼り付けるだけの簡単な感じにできるかなー。さすがにSS-520の打ち上げまでには起きられない気がするので、そっちも含めてあとでアーカイブ見ようっと。
*/

2017年1月14日土曜日

画像ビューア

メインで使ってるデスクトップPCには画像ビューアとしてPicasaが入っていて、大抵の用事はこれで足りてる。が、今回、高解像度な画像を表示できない事が発生してきた。
具体的には、16384x16384(Zoom6の世界地図規模)だと問題ないが、23040x22528(Zoom10で日本全国規模)では表示できない。前者はPNGで100MBほど、後者は45MBほどなので、画像自体の容量とかは問題ではないと思う。もちろん圧縮データの大きさなんて比較しても意味ないのだけど。

PicasaはPNGの透過も扱えるので、1ピクセル32bitとして前者は、1GiBちょうど、後者は1.93GiBくらいある。Picasaは32bitで、使用できるメモリ量は2GBに制限されるため、画像データを展開するメモリを確保するだけでいっぱいいっぱいで、展開作業とか、画面への表示とかを行う余裕もないのだと思う。

ということで、1辺2^14ピクセル四方くらいの画像より大きい画像を開くには何か別のプログラムが必要になる。
画像ビューアとして快適かというと微妙なところだが、とりあえず手元にあるアプリではPaint.netが問題なく開けた。64bit版が入ってるので、CPU速度の制限程度しかない。ま、非圧縮時で2GBのデータを開くと考えれば妥当な待ち時間だと思う。

他に何か良いのないかなと思ってぐぐったところ、Honeyviewというアプリが出てきた。これも64bit版があり、大容量の画像を開くのは問題ない。ただし操作感がいままでに触ったことがない感じで、マウス操作の挙動も独特だから慣れるのが大変かも。



世間を探すと、学術目的の画像ビューア(というかデータビューア)があって、超高精度の美術品スキャンデータとかみたいなものを見る用途で有るらしい。僕の用途も高解像度地図を開きたいわけで、この方向性になる。詳しく調べてないけど、学術用途なりの値段がしそうだなーという感じ。
博物館が所蔵品の高解像度スキャンとかを一般に公開するような時代になれば、その流れで大容量画像を表示するソフトウェアも普及するのかもしれない。でも、表示手段がないから博物館が出し渋ってる、みたいな卵鶏問題になるのかも。
元データがどれくらいで、公開にあたってどれくらいリサイズされてるのかわからないけど、スミソニアンのデジタルアーカイブだと長辺3000pxくらいの常識的なサイズだった。表示手段が一般的でない以上はこれくらいが落とし所なんだろうなぁ。


ベントレー、530億ピクセルの超高解像画像を公開 - 【自動車業界ニュース】 - carview! - 自動車
530億ピクセルの正方形画像として、1辺23万pxくらい。とはいえWebブラウザで表示できる程度に(ものすごく)縮小された画像を見てるだけだし、必要に応じてトリミングしてリサイズした画像を出してるだけだろうから、高解像度って言うとなんかびみょーな気がする。
同様に、こういう話題性みたいなので出て来る高解像度画像はいくつか有るらしいが、たぶん似たようなもんだと思う。


とりあえず、比較的低解像度(非圧縮32bit/pxで1GB程度まで)はPicasaが操作性や動作速度ともに問題なし。それ以上になると読み込みに時間がかかるがPaint.netが優位、という感じかな。
Paint.netはスケーリング時にリサイズされた画像を生成するらしく、その時に引っかかりが有る。スケーリングしないでスクロールだけなら結構サクサク動く。ただしビューアじゃなくエディタだから、マウス左クリックとかすると書き込まれるという難点が有る。これは慣れるしかないかなぁ。


ズーム12で北海道地域を画像化すると横3万、縦2万くらいの解像度になる。z14だと1辺4倍で12万x8万くらい。かなりでかいね。未圧縮で8GBの画像データかぁ。それでも高精細デジタルアーカイブに比べればケタ違いに小さいらしいんだけど。


あと画像ビューアからは少し離れるが、C#を64bitビルドにしてもSystem.Drawing.Bitmapのライブラリは32bitに制限を受けてるっぽい。解像度が23170x23170までは問題ないが、23170x23171になるとコンストラクタで例外が発生する。前者は32bit/pxで1.9999918GiBくらい、後者は2.000004GiBくらいで、ちょうど2GiBの境目にいる。ちなみにFormat24bppRgbをコンストラクタに渡すと、24bit/pxになるため、26754x26754くらいまでは作成できる。微々たる違いだけど。64bitネイティブのコアライブラリってないのかね。せっかく画像データの大半が解像度を32bitで管理してるのに15bitも使えないなんて。
コレについてはもしかしたら32/64bitの話ではなく、C#の設定で逃げれるっぽいけど、長くなったので今日はここまで。

2017年1月13日金曜日

日本周辺の標高

前回(世界の標高)の続きです。前回は世界全体の標高だったので、今回は日本周辺の標高です。


全体的に暗いのが通常スケール、全体的に明るいのが対数スケールで着色した画像です。通常スケールでは標高の高い山脈等は綺麗に見えますが、平地のダイナミックレンジが狭いという欠点があります。逆に対数スケールでは比較的なだらかな場所でも標高の変化がわかりやすいのですが、山脈のような部分は一様に塗りつぶされてしまうという問題があります。平地を重視するなら対数スケール、山脈や直感を重視するなら通常スケール、という感じでしょうか。



この画像は一部をトリミングしたものになります。最初の画像と同様に通常スケールと対数スケールで、レンジは同じです。
通常スケールでは山脈の谷間が綺麗に見える一方で、関東平野のあたりは一様に塗りつぶされています。
逆に対数スケールは山脈の形状を把握するのは困難ですが、平野のわずかな凹凸を把握することが可能です。


もうちょっと細かいところまで見たいので、次はDEM10Bのデータを使ってみようかと思います。こっちはz14まであるので、今回の画像の64倍細かいところまで見えるはずです。データ量も凄まじいことになるんでしょうけども。


// 年明けてからこっち、真面目な話題ばっかりなので、そろそろネタに走った何かやらなきゃなぁ。。

2017年1月12日木曜日

世界の標高


地理院タイルの標高データを画像化してみました。この画像はz2で1024x1024です。とりあえずz6までは画像化してみましたが、z6ともなると16384px四方で、画像データのくせにPNGで70MBくらいあります。z7だとこの4倍、z8だと16倍になりますから、想像するのも嫌な感じです。単純計算でz8だと画像で1GBくらい、元データで16GBくらいになるはずです。

とりあえず一番目立つのはチベット高原だと思います。高解像度で見ると谷間がありますが、z2くらいだと全体的に高地になっている感じです。
他にはアンデス山脈なども目立っていますね。あとはグリーンランドが全体的に高い感じでしょうか。
一番想像を裏切るのが南極大陸じゃないかと思います。雪で均されているのか、とても均一に標高が高くなっています。南極には富士山より少し高いエレバス山という活火山がありますが、この地図ではちょうど右下の角のあたりになります。



z6から本州と北海道だけを取り出すとこのような感じになります。データの関係で九州と四国が本州と地続きになっています。

世界地図の標高と同じスケールなのでダイナミックレンジが狭いですが、なんとなく山脈が有るのはわかると思います。
富士山のあたりはピンで突いたような大きさで標高が高くなっています。しかし周辺の山脈も結構高いので、富士山だけ飛び抜けて高いという感じもありません。


普段は地図を標高で見るという機会は多くないので、こうしてみると色々と面白いものですね。

C#のConsoleにプログレスバー

C#のConsoleアプリで時間が掛かる処理を行う時にプログレスバーが欲しいので作ってみた。

static void SetProgress(int Value, int Max)
{
    Console.Write(Value + "/" + Max + " ");

    int w = Console.BufferWidth - Console.CursorLeft - 1;
    int p = ((Value * w) / Max);

    Console.Write("".PadRight(p, '*').PadRight(w, '-'));

    Console.CursorLeft = 0;
}

ControleのProgressBarと違ってMinimumは無いのでオフセットは各自で処理するように。
ループとかに入る前にはConsole.CursorVisibleにfalseを入れてカーソルを表示しないように、ループが終わったらtrueを入れてカーソルを表示するようにする。
プログレスバーを表示中には改行を行ってはならない。またSetProgressは改行を行わない。ループを抜けた時にはConsole.WriteLine();で改行すること。
プログレスバーの後ろに追加情報を表示する機能は実装していないが、プログレスバーの前に追加情報を表示することはできる。そういうことを行いたい場合はSetProgressを呼ぶ前にConsole.Writeを使って表示すること。重ねて言うが、Console.WriteLineを使ってはいけない。
ただしカーソル位置を呼び出し元で管理している場合は改行やカーソル位置の変更に制限はない。もっとも、プログレスバーの開始位置は任意なれど、終了位置は常に右端だから、コンソール内でGUIを作るにはあんまり向いてない。

当たり前だが、Paralell.Forとかの中で呼ぶとひどいことになる。シングルスレッドで使うことを前提としている。それからウインドウ幅(バッファ幅)が足りない場合の挙動とかは未確認。


たまに欲しい時にいちいちソースコード探すのが面倒なのでブログに貼り付けておく次第。