オペアンプをコンパレーターとして使って見る:今岡通博の俺流!組み込み用語解説(12)(1/2 ページ) - MONOist
直流用フォトカプラをAC100Vに繋いでた人。この人にこの手の記事書かせ続けて大丈夫? 個人運営ブログの学習メモとかじゃあるまいし、「モノづくりスペシャリストのための情報ポータル」を謳うサイトが組み込み(電子回路)をターゲットに解説記事を連載するなら、その分野である程度経験のある人に頼んだほうがいいと思うんだけど。
今週は某ゲームを遊び込んでたので進捗だめでーす。
YouTubeのアルゴリズムの問題なのか、某ゲーム、「殴ったり燃やしたりしても良いコンテンツ」として扱われているような印象になってて残念。大手ゲームメディアとかだとそこまで火をつけて遊んでるわけじゃないし、というか普通のゲームとそう変わらない扱いだし、一部のメディア(主にYouTubeとか個人運営サイトの「反応まとめ」的なコンテンツ)がそういう遊びをしてるんだろうけど。/* そういうコンテンツ1回も見たことないしなんなら時々チャンネル自体ブロックしてるのにそれでもなお執拗にクリックベイトをオススメしてくるYouTube君のアルゴリズムさぁ。。。 */
プレイキャラの切り替えができるようになるまでプレイ時間24時間くらいかかった。あちこち寄り道したとはいえ、序盤だけでこのボリュームか……
ゲーム内時間経過で一定時間が経つと次のファストトラベルで季節が入れ替わるシステムは面白いけど、それがゲーム性に反映されているかというと微妙な気がする。冬は走るのも遅いし、遮蔽になる植生もないし、植物に入るとカサカサ音がなったり屋根の上を歩いたら氷柱が落ちたり。冬はちょっと面倒。せめて積もった雪に隠れることができればよかったんだけどな。夏と冬でゲーム性結構変わる気がする。うまく季節に合わせた立ち回りを考えないと。
エンジンが同じだからか、GRBPっぽさもある。GRBPは平面方向でしか動けなかったけど、ACSはパルクール的に建物の上とかに行けるのが楽しい。操作性に若干難ありという感じだけど。
オープンワールドは移動が多くて、ACSは世界観的に車とか飛行機とかヘリコプターとかが使えないから、とにかく走るしかない(or馬に乗る)。GRBPと違って体力ゲージが無いから、走るときに体力管理が必要なのが嬉しい。あと崖を滑り降りるときにHPが削られないし。Zキーで自動で歩き/走りしてくれるるけど、それでも進行方向は自分で調整しなきゃいけないから、長距離を移動したいときにちょっと面倒。まっすぐ突っ切ろうとすると地形が厳しいし、道なりに行こうとすると遠回りだし。せめて馬に乗ってるときは目的地の近くまでは自動で歩いてほしいな。ゆっくり周りを見て移動するとかもできるし。
ゲームの設定でキー入力のソースを1個しか設定できないのが地味に不便。例えば回避のデフォルトはAltだけど、これをマウスのサイドボタンに割り当てようとするとAltが削除されるから、クセでAltを押すと回避できない。せめてキーボードとマウスは区別して(重複して)設定できると便利なのだが。
例によってサブスクで遊んでるけど、ゲーム自体は楽しめているし、ライセンス1本買おうかな、と思ったり。Ubi版で遊んだ履歴ってSteam版を買っても引き継げるんだろうか? 今までのUbiのゲーム、例えばThe DivisionとかGRBPはSteam版で買ってもUbiのランチャーで起動するからSteam版/Ubi版の区別なくセーブは共通だろうけど、ACSのSteam版はUbiランチャー不要だそうだから、セーブデータの引き継ぎに難がありそう。どうしてもSteam版を買わなきゃいけない理由もないので、Ubiで買ってもいいんだけど。
安いゲーミングマウスを買ってみた。ちょっと前に買ったキーボードと同じブランド/デザインのやつ。
FPSだとあまり気にならないけど、剣を振り回したりするゲームだととにかくクリックを連打するから、マウスの寿命が心配。/* ACSの場合、1段くらいのキュー経由っぽくて、連打するとパリィが間に合わなくなるから、本当は連打しちゃだめなんだろうけど */
今まで使っていたやつと並べて使うと新しい方のカーソルがめっちゃ引っかかる。amazonのレビューも低評価ちょっと多かったしなぁ……と思いつつ有線で接続したら問題なく動く。試しに古い方のドングルを抜いてみたらヌルヌル動くようになった。USBハブにドングル2個並べていたから、古い方のドングルから出ている電波が新しい方のAGCをリミットさせているのかな。無線機器を並べて使う経験がほとんど無いので、目に見えて抑圧を受けたのは初めてのような気がする。
古い方は海外のブランドなので結構大きいし重い。新しいやつは国内のメーカーだからかひと回り小さくて持ちやすいし軽い。ガッツリ肉抜きしてあるFPS用のマウスならもっと軽いんだろうけど。
古い方は充電ドッグ(別売り)に乗せれば簡単に充電できるけど、新しい方はType-C専用なので充電するたびに挿抜しなきゃいけないのが面倒。ただ、古い方は1日で50%くらい電池を消耗するから毎日の充電が必須だけど、新しい方はそこまで極端に放電するわけじゃないから、数日毎に充電すれば良さそう。それはそれで忘れそうとか不安だけど。
コネクタがもっと手前にあれば磁石で簡単に着脱できるアダプタを使えるのに、なぜかゲーミングマウスのUSBコネクタってかなり奥まった場所にある印象。新しい方は普通のType-Cケーブルが使えるだけまだ良心的。古いやつはコネクタこそMicro Bだけど、細い穴の奥にコネクタがあるせいで市販のUSBケーブルが使えない。テーパーみたいな構造もないからUSBを刺すのがかなり面倒だった(だからしょうがなくドックを買ったわけだが)。新しい方も、付属のケーブルは普通のType-Cより被覆が大きくて、スリットが入った構造になっている。もしかしたらマウスを振り回したときにType-Cコネクタじゃなくてその周りの樹脂パーツで負荷を受けるような意図なのかな? 古い方のマウスも同じ思想なのかも。専用ケーブルしか使えない古い方に比べて、市販のケーブルでも(コネクタにダイレクトに負荷がかかるとはいえ)使い回しができる新しいほうが親切感がある。
ユーティリティでいろいろ設定できるけど、ボタンに割り当てられる機能が少なめなのがちょっと不満。例えばDPIはいくつかの種類を設定できて、ボタンで切り替えられるけど、DPI切り替えが1方向しかない。2個のボタンでDPI Up、DPI Downみたいな操作が作れない。不思議。ホイールの手前に2個のボタンが付いていて、普通のマウスはここにDPI Up/Downが割り当てられていたりするはず(デフォルトでは無割当)。
左右クリックとサイドボタンはマイクロスイッチっぽい感触だけど、中クリックはタクタイルスイッチっぽい感触。あっという間に死にそうだなー。ホイール手前のボタンに中クリックを割り当てるという手もあるが。
ホイールはクリック感強めで結構好み。
最初は軽すぎる感触とかが不慣れで変な感じだったけど、慣れてしまえば結構快適。
古い方のマウスはサイドパネルを交換すれば12ボタンにいろいろな機能を割り当てて、右手だけでほとんどのPC操作が完結するのが便利だったけど、マウスがスリープに入るとウェイクアップに時間がかかるのが不便だったんだよなー(立ち上がるはテンキーモードになっているから数字が連打されて、いちいち消さなきゃいけないのが面倒だし、YouTubeとか見てると不用意にシークしてしまう)。あと、FPSを遊ぶときにサイドボタンが邪魔で2パネルに交換していたから、サイドパネルのショートカットも使えていなかったし、普通のマウスに変えてもそんなに違和感無い。もう一つマウスを買ったんだから12ボタンパネルに戻してもいいんじゃね、とは思いつつ、抑圧の問題がなぁ。こっちのマウスは有線で接続すれば、抑圧もないし、スリープに入ることもないし、「右手デバイス」的に使うのであれば問題ないかな? マウスを2個も置くスペースが無いという大問題を除けば。
世界の重要インフラを強くする!時刻同期は2周波GNSS受信の時代へ | 技術 | GPS/GNSSチップ&モジュール | フルノ製品情報
あくまでも周波数ダイバーシティ的に使っているだけであって、L1/L5で電離層遅延を推定する、みたいな感じではないのかな。L1を妨害されてもL5を受信できていれば問題ないよ、L5を妨害されてもL1を受信できていれば問題ないよ、L1もL5も妨害されたらフリーランするけどそれでも短時間なら十分な精度を維持するよ、みたいな。
衛星の打上げ、神社等で成功祈願を行っていない衛星はトラブルを起こしやすい、というジンクスがあるらしい(1990年前後の話)。祈願に行ける程度にスケジュールに余裕があるときは地上で対応できるトラブルは対応済みだが、祈願に行けないほど打上げ直前まで対応に追われていると不具合を潰しきれていないから、という相関関係らしい。まさに人事を尽くして天命を待つという感じの。天命を待てない場合は人事を尽くせていない。
1980年代末頃にESAから提案されていた測位衛星NAVSAT、18機とか24機とか何種類か提案されていたけど、地上の原子時計をベースにベントパイプで測位信号を放送して、4機から信号を受信することで測位する。
SBASは静止衛星でGPSの補正信号を送るシステムで、これはベントパイプで放送を行うが、オプションで測位信号を放送することもできる。
ベントパイプで測位信号を放送する場合、衛星軌道に起因する相対論的効果は発生しない。全地球規模でベントパイプで放送するには地上局を満遍なくある程度の数(最低3箇所、できれば6箇所とか8箇所とか?)配置する必要があるから、今の地球のみたいに陸地の配置が非等方的な惑星の場合は地上局の配置に制約があるけど、それにしたって例えば衛星間中継を行うとか、どうにでもできるはず(衛星間通信みたいな方式だとアンテナゲインを稼がなきゃいけないから機械可動部が不可欠で、そのあたりの信頼性が、黎明期のオンボード原子時計と比較してどうかという問題はある)。
多少なりとも相対性理論を解説しようとする文脈では「衛星測位を行うには相対性理論が必須」というような説明が判で押したように出てくるけど、本当にそうなのか怪しい気がするんだよなぁ。人間のスケールではほとんど効いてこない相対論の研究に無理やり理由をつけるために使っているだけのような気がする。
結局、現在の衛星測位システムはすべて軌道上に原子時計を搭載しているから、なんだかんだ原子時計を軌道上に置くほうが色々と楽なんだろうけど。そのせいで飛行機とか高信頼性の用途で使おうとしたときに面倒なことになってるんだけどな。。。
ベントパイプなら軌道上で時計が壊れたり計算をミスって誤った信号を放送する心配がほとんどない。中継機が壊れた場合は単に信号が中断する場合が多いから受信機はそれを無視するだけで済むし、そもそも全ての衛星が地上局から可視なのが前提だから、中継機の特性が悪化して測位精度が劣化するような場合でも地上局で検知して放送を中断すればいいだけだし。
軌道上に原子時計を置くもう一つの利点として、地上局から独立して動作できるという利点がある。つまり地上局が壊れたり壊されたりしても、しばらくはシステムとして稼働できるから、軍用のシステムとして考えたときに便利(1箇所の地上設備が破壊されるだけでその周辺数千kmで軍事作戦が全部支障を受ける、みたいな脆弱性が無い)。NAVSATがベントパイプ方式で考えていたのは民間用の測位システムとして考えていたからだろう。
なんとなく思い至ってrtlsdr.dllをC#から叩いてみた。
非協調型のDLL(Visual Studioでメソッド一覧を取れないという意味で)をC#から叩くのってもっと大変だと思ってたけど、かなり簡単に叩けるんだな。リンカで公開されている関数の一覧を得て、ソースコードから引数とか戻り値がわかるから、それに従ってLibraryImportを書いていくだけ。
rtlsdrライブラリはOpenに構造体のポインタのポインタを渡して、その他関数(Close含め)は構造体のポインタを渡す。構造体の中身に触らないのであれば、C#側からはIntPtr(Openはref IntPtr)を渡すだけ。基本的に全部静的メソッドとして定義するので、いちいちIntPtrを渡さなきゃいけない(or IntPtrを持つインスタンスとそれを使ったオーバーライドを作らなきゃいけない)のが面倒くさい。
前にC#のRTLSDRラッパーのコードを見たときに、結構複雑そうなことをやっていた記憶があるけど、最低限必要な部分だけ書くなら、結構簡単。
まだ複数ドングルの同時接続は試していないから、もしかしたらそのあたりは大変かもしれないけど。rtl_tcpだって実際はrtlsdr.dllを呼ぶような実装だろうし、多分問題ないと思うんだけど。
試しにDLL直叩きで1575.42MHzを2.4Mspsでサンプリングしてみた。問題なくデコードできるけど、長時間サンプリングしても数分程度しかデコードできない。適当な時刻オフセットを与えてやれば別の場所をデコードできるけど。たぶんドロップしているんだろう。
ドロップがrtl_tcp.exeとかの問題ではなくて、少なくともDLLレベル以下か、ハードウェアに起因するんだろう、というのがわかっただけでも収穫。まあ、DLLから配列を受け取ってファイルに書き込むなんて非常に簡単な処理だし、こんなところにバグの入り込む余地はほとんど無いだろうし。
rtl_tcpとDLL直叩きを比較して、どちらに大きな優位点があるというのはあまりなさそう。DLLで叩ける機能はだいたいTCP経由でも叩けるし。
DLL経由とrtl_tcp経由で一番違うのがゲインの設定かな。DLL経由の場合、R820T2(orその他のフロントエンドIC)が対応するゲインを正しく設定する必要があって、対応していない数値を与えた場合は単に無視される(近いゲインに設定されるわけじゃない)。対応していない値を設定した場合に無視されるのはrtl_tcpでも同じ(rtl_tcpも結局同じ関数を呼んでいるだけなので)。
ただしrtl_tcpはゲインを番号で指定するコマンドがあって、この場合、範囲内の番号を指定すればゲインを設定できる。この番号は例えばR8xxの場合0以上28以下の範囲の自然数を指定する。ゲインを指定する場合は規則性のない数値(R8xxの場合0から496までの29種類)を指定する必要があるから、インデックスで指定するほうが簡単。
しかし、このインデックスはフロントエンドICによって指定できる数は異なり、対応するインデックスより大きい値を設定した場合は単に無視されるから、結局、適当な巨大な数(例えば1000とか)を設定しても無視されるのはgainコマンドもgain by indexコマンドも同様。
DLLを叩く場合、対応したゲインの数値の一覧を得ることができるから、適当な値(例えばR8xxでは対応していない40dB)を設定しようとしたときに、対応するゲインの一覧から一番近い数値を自動的に設定する機能を作ることができる。この場合、適当な巨大な数を設定すれば、それに一番近いゲイン、すなわちそのフロントエンドICで設定できる最大のゲインが設定されるから、フロントエンドICの種類とか使用できるゲインの数値とかを気にする必要がない。
ただしこの一覧を得る関数はintポインタを引数に取って一覧を配列に書き込むから、呼び出し側でmalloc/freeで取得した配列(あるいはあまり多くないことを期待してスタック領域で宣言した配列)を渡す必要がある。こういう処理は普通のC#に比べるとちょっと手間がかかる。とはいえ、数行程度のメソッドを1個書けば隠せる程度の処理ではあるが。
GPSの受信もちまちま実装中。
C/Aコードのロックオフの検出をPLLで実装してみた。今までは航法メッセージのパーサで検出していたので、数秒程度の遅れがあって、その間の測位データが大きな誤差を持っていた。
PLLがロックオンした状態ではフィードバックは±1rad程度に十分収まるが、ロックオフした状態ではフィードバック値が±πradにランダムに分布することを利用して、閾値(例えば±π/4rad)を超えたフィードバックが適当な割合(例えば25%)を超えた場合、ロックオフしたと判定し、相関器・受信機をリセットしてドップラスキャンを行う。閾値にもよるけど、数百ミリ秒程度で搬送波ロストを検出できるから、航法メッセージを見るより1桁早い。閾値を狭くすればもう1桁早くなるけど、ノイズに弱くなる。
以前遠出したときにサンプリングした30分くらいのIQファイル(途中で何回かドロップしている)を解析して、結果全期間を復調できるようになった。観測値(GPS衛星時刻)を100Hzで出力して、そのまま測位演算してNMEA0183で出力しているから、GGAだけしか出していないのに12MB(17万行)を超えている。点数が多いせいかGoogle Earthで表示できない。高度ビューは見れるし、カーソルに合わせて三角形のマーカーが移動するから、正しそうな位置が得られているのはわかるんだけど。
今のところ、IQファイルの復調は各GPS衛星が放送している時刻(普通のGPSで言うところの擬似距離に近い情報)をファイルに書き出して、その後で測位演算を行っているので、GPS衛星の捕捉に推定値を使うことができない(最後にロックオンしていたときのドップラを持っておくとかの方法はあるけど)。GPS衛星の受信と同時に測位演算を行っておけば、現在位置・速度・受信機クロックエラーから衛星のドップラや航法メッセージの位置(ビット内外の位相)を推定できるから、より早く再補足ができる。ただ、この場合は測位演算が継続していることが大前提であって、例えばRTL2832Uのサンプルドロップは全衛星が同時に断してその量もわからないから(数us程度のはずだけど)、相関器や復調器はリセットする必要がある。
PLLの記事で、IC用のクロックとか無線機の修理とか、いろいろな文脈で「PLLのロックが外れる」みたいな表現が出てくるけど、ではそれをどうやって検出するか、という話はほとんど出てこない気がする。一部のPLL ICにロック検出回路を内蔵しているものがあるけど、とはいえその詳細な説明とかは見当たらない。
クロック回路のエンジニアとしては安定して動作するPLLの設計が腕の見せ所(というか安定して初めてマトモな設計になる)だし、古い無線機の修理とかではPLLが外れる=正常に動作していないわけだから、いちいちPLLのロック状態を把握しなきゃいけない状況ってのは少なそう。どうしてもクロックの監視が必要なら、そのクロックでカウンタをインクリメントしたうえで、適当な高信頼のクロック(数十kHz程度)でカウンタをリードandクリアして、カウンタがゼロ(or適当な範囲外)の場合はクロックエラーとして割り込みをかける、みたいな機能でいいはずだし、PLLだけ見てもあんまり意味ないだろうし。
通信分野だと相手の信号の有無を検出したいみたいな場合もあるけど、それにしたって例えば放送(デジタルテレビとか)ならOFDMのガードインターバルを探すとか、受信した情報の誤り率を見るとか、そもそも信号の判定をしない(SNRが悪ければ単にブロックノイズとしてユーザーに提供する)とかだし、通信(移動体通信とか)にしても上位プロトコルで判定することが多いだろうし、搬送波レベルで信号のロストを検知したいって用途は結構レアなのかもしれない。
宇宙機の通信だと地上からCWをスイープしてオンボードのPLLでこれを検出・ロックして地上に折り返して、地上でもキャリアを検出してロック判定、みたいなことをやるけど、こういう手順の(搬送波レベルでハンドシェイクする)通信方式って宇宙通信の他にあるんだろうか。
C#のメソッド(というかコンストラクタ)でトップのブロックを書かずに;で終端するような機能欲しいよなー。record Hoge(int Value){public Hoge(string str)this(int.Parse(str));}みたいな感じで、thisで別のコンストラクタを呼ぶだけで、中で何も処理しないときに空のブロックを書かなくて済むように。わざわざ専用の文法を用意するくらいなら空ブロック書くほうがマシ、ということなんだろうけど。
C#のSpan<T>/ReadOnlySpan<T>と同じように使えるSpan<T1, T2>/ReadOnlySpan<T1, T2>みたいな構造が欲しいなーと思ったり。
大量の複素数をComplex[]で持つのでなく、float[]real, imaginaryで分けて持ったりするときに、それぞれを一体として扱ったり、必要に応じてFirst, Secondで個別にSpan<T>を切り出したりできるようなやつ。
既存のC#でも例えばArrayとかSpanのSort<TKey,TValue>(TKey[],TValue[])みたいに2種類の形(2個の配列)をあわせて使うような機能はあるわけだし、それを積極的に使うようなサポートがあっても良さそうな気がする。Arrayならともかく、Spanの場合は切り出して使うのが前提だろうし、それなら両方をまとめて切り出すような機能も欲しい(切り出しを2回書かなくていいから、ソースコードが半分で済む)。
ついでにSpan<int,int>spanみたいなやつをvar(a,b)=span[0];とかforeach(var(a,b)in span)みたいな感じで一括で読めるような機能があるとなお嬉しい。
0 件のコメント:
コメントを投稿