コグノスケ


link 未来から過去へ表示(*)  link 過去から未来へ表示

link もっと前
2024年10月21日 >>> 2024年10月8日
link もっと後

2024年10月21日

OpenPilotを調べる - プロセス間通信msgqの仕組み

目次: OpenPilot

最近はOSSの運転支援ソフトウェアOpenPilotのコードを見ています。今日はOpenPilotのプロセス間通信について調べます。

OpenPilotは複数のプロセスが共有メモリを通じてデータを送受信しています。データ送受信のモデルはPublisher/Subscriberモデルを採用していて、1つの通信チャネルについて1つだけPublisherがいてデータ送信役を担い、複数のSubscriberがいてデータ受信役を担います。Client/Serverモデルとは異なりデータはPublisherからSubscriberへの一方通行で、SubscriberからPublisherに送ることはできません。

Publisher/Subscriberの仕組みの名前が見当たらなかったので、関連するコードのディレクトリ(openpilot/cereal)からcerealと呼びます。画像用のPublisher/Subscriberの仕組みだけ特別にVisionIpc(openpilot/msgq/msgq/visionipc)と名前が付いていてcerealと実装が異なりますが、背後にあるデータ送受信の仕組みmsgq(openpilot/msgq)は共通です。

実装箇所

今回の着目点はmsgqですから、cerealとVisionIpcの違いは扱いません。簡単に双方ともmsgqを使う経路がある説明だけに留めます。

まずcerealです。cerealはPython用およびC++用のクラス定義を行っています。Publisher用がPubMaster、Subscriber用がSubMasterです。PythonもC++も同じクラス名で、クラス定義、実装箇所は下記のとおりです。

  • Python用: openpilot/cereal/messaging/__init__.py
  • C++用: openpilot/cereal/messaging/socketmaster.cc

背後のデータ送受信の仕組みはopenpilot/msgq/msgq/msgq.ccにあります。関数がプレフィクスmsgq_から始まるので見分けやすいです。cerealのPubMaster/SubMasterからmsgqのコードに至る経路は下記のとおりです。

cerealの実行経路の概要
PubMaster::PubMaster()
  PubSocket::create()
    MSGQPubSocket::connect()
      msgq_new_queue()

SubMaster::SubMaster()
  SubSocket::create()
    MSGQSubSocket::connect()
      msgq_new_queue()

次にVisionIpcのServer/Clientからmsgqのコードに至る経路は下記のとおりです。コンポーネントによって呼び出し元は違うので、例としてPublisher側はreplayのCameraServer、Subscriber側はuiのCameraWidgetからの経路を挙げます。

VisionIpcの実行経路の概要
CameraServer::startVipcServer()
  VisionIpcServer::create_buffers_with_sizes()
    PubSocket::create()
      MSGQPubSocket::connect()
        msgq_new_queue()

CameraWidget::vipcThread()
  VisionIpcClient::VisionIpcClient()
    SubSocket::create()
      MSGQSubSocket::connect()
        msgq_new_queue()

経路は多少違うもののcerealもVisionIpcも両方ともmsgqに行き着きます。ただしcerealはmsgq以外の経路(ZMQ)が選択可能で、ZMQを選択した場合は上記と異なる実行経路となります。

msgqのデータ共有方法

ファイルの共有メモリマップをお互いのプロセスから読み書きしてデータ共有します。msgq_new_queue()にて/dev/shmにあるtmpfsファイルシステム(メモリ上にファイルシステムを作る仕組み)上に1つの通信チャネルごとに1つファイルを作成します。1つのファイルをPublisherとSubscriberが共有メモリマッピングするので、お互いに同じファイルのデータが見えます。Publisherがメモリマップ経由でファイルを書き換えたらSubscriber全員に変更が見える仕組みです。

通常、ファイルの共有メモリマップに書き込んだ内容を他のプロセスに可視化するときはmsync()を呼ぶ必要があります。しかしmsgqの実装はtmpfs決め打ちというか、msync()の手間を惜しんだのか、atomicアクセスもしくはメモリバリア__sync_synchronize()だけで済ませています。うーん?これでも動くんだ……?

msgqの変更可視化の実装例(Publisher側のsend)

// openpilot/msgq_repo/msgq/msgq.cc

int msgq_msg_send(msgq_msg_t * msg, msgq_queue_t *q){
  //...

  //★★q->dataは共有メモリマップへのポインタ★★
  char *p = q->data + write_pointer; // add base offset

  //...

  // Write size tag
  //★★atomicアクセス★★
  std::atomic<int64_t> *size_p = reinterpret_cast<std::atomic<int64_t>*>(p);
  *size_p = msg->size;

  // Copy data
  //★★memcpy + メモリバリア★★
  memcpy(p + sizeof(int64_t), msg->data, msg->size);
  __sync_synchronize();

ファイル内のデータは下記のようにヘッダ領域とデータ領域の2領域からなります。各プロセスにはmsgq_queue_t構造体が確保され、ヘッダ領域とデータ領域へのポインタを保持します。


msgqのデータ共有用ファイルの構造

データ領域のサイズはDEFAULT_SEGMENT_SIZE(10MiB)固定です。Subscriber数の最大数はread_pointers[]などの配列長で決まります、現状だとNUM_READERS(15)固定です。なぜ16じゃなくて15なのか?理由が良くわかりません。特に理由は書いていませんでした。

msgqのデータ構造体(一部)

// openpilot/msgq_repo/msgq/msgq.h

#define DEFAULT_SEGMENT_SIZE (10 * 1024 * 1024)
#define NUM_READERS 15
#define ALIGN(n) ((n + (8 - 1)) & -8)

struct  msgq_header_t {
  uint64_t num_readers;
  uint64_t write_pointer;
  uint64_t write_uid;
  uint64_t read_pointers[NUM_READERS];
  uint64_t read_valids[NUM_READERS];
  uint64_t read_uids[NUM_READERS];
};

struct msgq_queue_t {
  std::atomic<uint64_t> *num_readers;
  std::atomic<uint64_t> *write_pointer;
  std::atomic<uint64_t> *write_uid;
  std::atomic<uint64_t> *read_pointers[NUM_READERS];
  std::atomic<uint64_t> *read_valids[NUM_READERS];
  std::atomic<uint64_t> *read_uids[NUM_READERS];
  char * mmap_p;
  char * data;
  size_t size;
  int reader_id;
  uint64_t read_uid_local;
  uint64_t write_uid_local;

  bool read_conflate;
  std::string endpoint;
};

PublisherとSubscriberが1プロセスずついるときはこんな感じです。msgq_header_tの実体は1つで、各プロセスのmsgq_queue_tがmsgq_header_tとデータ領域へのポインタを保持します。


PublisherとSubscriber間のtmpファイル共有

データ領域はPublisherが書き手、Subscriberが読み手のリングバッファとして機能します。つまりPublisherはデータ領域に送信したいデータを書いてwrite_pointerを進め、Subscriberはデータ領域からデータを読み取ってread_pointerを進めます。

編集者:すずき(2024/10/25 02:18)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2024年10月20日

ゲームを買ったら遊びましょう2

目次: ゲーム

前回の振り返り(2022年5月13日の日記参照)から2年半経ちました。所持しているゲームのリストを見るとほとんど変わっていなくて、最近ゲームしてないことが良く表れてます。特に続編系は情熱をもって遊べていないですね。小規模ゲームはいくつかクリアしました。

Skylines 2
順当な続編である印象を受けますね、システムは大体一緒です。リリース直後はゲームバランスが変で遊ばなくなりました。そのうち改善されるでしょう。
スプラ3
初めから超絶ボコボコにされてやる気ゼロになりました。下手くそには辛い。
Wizardry外伝
初期のWizardry目指して作った感じですかね?昔のWiz好きなら面白いと思います。追加シナリオ1個(戦闘の監獄、Prisoners of the Battles)をクリアしましたが、基本シナリオ5個全部クリアする元気はありませんでした。
熱血硬派くにおくん外伝
くにおくんシリーズを裏切らない、たくさん出てくる敵をボコボコにしていくシステムで面白いです。が、私はアクションが基本的に好きではなくて、あまり続きませんでした。
8番出口
地下鉄の通路を思わせる道に起きた異変を察知しながら脱出を試みるゲームです。短いながら面白かったです。アイデアの勝利ですね。

振り返り結果

クリアした(実績90〜100%、シナリオコンプなど)。

  • 332.9: Steam: Cities: Skylines
  • 192.8: Steam: STATIONflow
  • 180.3: Steam: Transport Fever 2
  • 68.5: Steam: Mad Tower Tycoon
  • 59.2: Steam: shapez.io
  • 35.0: Switch: DUNGEON ENCOUNTERS
  • 23.3: Steam: ぶきあつめ (The World is Your Wepon)
  • 10.0: Switch: Return of the Obra Dinn
  • 1.0: Switch: ごめんね、NPCです
  • 1.0: Steam: 8番出口

たくさん遊んだ(クリア条件がないor困難すぎて挑む気なし)。

  • 413.3: Steam: Dyson Sphere Program
  • 170.0: Steam: the Hunter: Call of the Wild
  • 95.0: Switch: スプラトゥーン2

未クリア(実績、シナリオクリア率が50%以下)。

  • 71.5: Steam: Surviving Mars
  • 63.9: Steam: Tropico 6
  • 55.0: Switch: Fire Emblem風花雪月
  • 44.4: Steam: Wizardry外伝 五つの試練
  • 39.4: Steam: Timberborn
  • 28.9: Steam: Cities: Skylines II
  • 28.9: Steam: Turing Complete
  • 21.5: Epic: DAEMON X MACHINA
  • 20.0: Switch: ザ・コロニスト
  • 15.0: Switch: マリオカート8デラックス
  • 15.0: Switch: A列車で行こう はじまる観光計画
  • 9.0: Steam: Freeways

ほぼ遊んでいない。

  • 12.3: Steam: Asset Corsa
  • 10.0: Switch: スイカゲーム
  • 9.0: Steam: Captain of Industry
  • 5.0: Switch: スプラトゥーン3
  • 4.8: Steam: OpenTTD
  • 4.0: Steam: Battlefield V
  • 3.9: Steam: Kerbal Space Program
  • 2.0: Switch: 熱血硬派くにおくん外伝 River City Girls 2
  • 1.0: Steam: Plate Up!

メモ: 技術系の話はFacebookから転記しておくことにした。

編集者:すずき(2024/10/25 02:22)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2024年10月14日

JTSA Limited練習記録2024

目次: 射的

スピードシューティングを始めてから2年半が経ちました。11月には3回目の参加を予定しているJTSA Limited(リミティッド - 一般社団法人日本トイガン射撃協会JTSA)が開催されます。

以前と変わらず、基本的に練習は週1回のみです。たまに練習以外のシューティング系イベントにも行きますが、記録を見る限りタイム上達とは関係なさそうです。2023年の結果はこんな感じでした。


JTSA Limited 2023年の記録

記録は横ばいで80秒台からタイムが早くなる様子がなく、週1回の練習ならこんなもんか?と諦めていました。ところが2024年の夏から70秒台のタイムが出るようになりました。何が起きたのかわかりません。謎です。


JTSA Limited 2024年の記録

今日は初の69秒台のタイムが出ました。とはいえ各ステージのタイムのゆらぎを見る限り、全ステージが偶然早いタイム側に寄っただけの偶然の産物です。実力は75秒くらいでしょうか。

ここ1か月は最近は1発目を早く撃てるように頑張りましたが、その前からなぜか早くなっていたし、何が良くなったのかイマイチわからないです。この後良くなるのか悪くなるのかわからないですね……。

編集者:すずき(2024/10/20 14:41)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2024年10月11日

企業のドメイン

今の企業は公式サイトを持っていなほうが珍しいと思いますが、ドメイン名の使い方は各社でバラバラで面白いです。特にグローバル企業は日本だけでなく世界各国向けに公式サイトを構築する必要があるため、迂闊に「会社名.co.jp」みたいなドメインを使うと海外展開時に困ってしまいます。

解決方法はいくつかパターンがあるみたいです。

  • gTLD(.com)ドメイン
  • gTLD(.com)ドメイン&ドメイン先頭(www部分)が地域名
  • ccTLD(汎用JPなど)ドメイン
  • 日本だけ属性型JP(.co.jp)ドメイン、他国はccTLD(汎用JPなど)ドメイン
  • 企業名ドメイン

一番良く見かけるタイプでオーソドックスな解決方法だと思われます。gTLD(generic Top Level Domain)である.comドメインのあとに地域名や国名を表すパスが続きます。ドメインを増やさずに各国地域対応が可能で、スマートですね。

  • アイシン: https://www.aisin.com/jp/, https://www.aisin.com/en/
  • デンソー: https://www.denso.com/jp/ja/, https://www.denso.com/fr/fr/
  • 電通: https://www.dentsu.com/jp/jp, https://www.dentsu.com/fr/fr
  • 三菱商事: https://www.mitsubishicorp.com/jp/ja/index.html, https://www.mitsubishicorp.com/fr/en/
  • Panasonic: https://www.panasonic.com/jp/about.html, https://www.panasonic.com/fr/
  • PlayStation: https://www.playstation.com/ja-jp/, https://www.playstation.com/fr-fr/
  • 住友商事: https://www.sumitomocorp.com/ja/global/, https://www.sumitomocorp.com/zhcn/easia/

亜流としてNECのように、.comドメイン&ドメイン先頭(www部分)が地域名になる会社もありました。.comドメインだけどパス名の代わりにドメインの先頭を使うんですね。これはこれでスマートです。

  • NEC: https://www.nec.com/, https://jpn.nec.com/, https://fr.nec.com/

もう一つはccTLD(country code Top Level Domain、つまり汎用JPドメインなど)を使う会社です。一貫性がありますね。

  • トヨタ: https://toyota.jp/, https://www.toyota.fr/

亜流として日本だけ属性JPドメイン(.co.jp)、他国はccTLDドメインを使う会社もあります。日本だけ違うのは過去の互換性のためでしょうか?

  • ホンダ: https://www.honda.co.jp/, https://www.honda.fr/
  • 日産: https://www.nissan.co.jp/, https://www.nissan.fr/
  • ソニー: https://www.sony.co.jp/, https://www.sony.fr/

珍しいパターンとしては企業名ドメインもありました。このタイプのドメインの名称が良くわからないんですが、企業名がトップレベルドメインになっています。でも他国向けはccTLDでした。謎の作りですね。

  • SHARP: https://global.sharp/, https://jp.sharp/, https://www.sharp.fr/
  • 東芝: https://www.global.toshiba/jp/top.html, https://www.toshiba.fr/pages/fr/

日本だけ特別扱い系の謎

日産やホンダは.co.jpを使っていますが、.jpはアドレス解決ができないところから使っていないように見えます。.jpドメインはどうなっているんでしょうか?Whois情報を見ると、

nissan.jpのwhois情報
$ whois nissan.jp

Domain Information: [ドメイン情報]
[Domain Name]                   NISSAN.JP

[登録者名]                      日産自動車株式会社
[Registrant]                    Nissan Motor Co., Ltd.

[Name Server]
[Signing Key]

[登録年月日]                    2001/03/26
[有効期限]                      2025/03/31
[状態]                          Active
[ロック状態]                    DomainTransferLocked
[ロック状態]                    AgentChangeLocked
[最終更新]                      2024/08/06 16:25:46 (JST)

見慣れない"DomainTransferLocked"と"AgentChangeLocked"が設定されています。これはドメイン名移転申請ロック、指定事業者変更ロックのことだそうでJPRSのサイト(指定事業者変更ロック - JPドメイン名のルール - JPドメイン名について - JPRS)に解説があります。

企業と関係のない登録者に勝手に使われないように申請を弾いてくれる仕組みですね。こんな機能があるとは知らなかったです、なるほど便利だ。

編集者:すずき(2024/10/25 02:19)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



2024年10月10日

shapezレベル100達成

目次: ゲーム

書くの忘れてました。放置してたshapezを夏ごろにレベル100まで進めました。レベル27から納品物がランダムになるので「何でも作れる機構」を構築しないとレベル100達成はしんどいです。

実績は41/45まで取りました。取り逃しは、取る気が元々ないスピードラン系3つ+操作ミスで取り逃した「King of Inefficiency」です。


shapezの実績

レベル100程度ならさほど納品速度は要求されませんが、高レベルになると作成したShapeを納品する場所(ハブ)に超高速で納品しなければならないです。何でも作れる機構+倉庫に大量のShapeをためて、たまったら一気に流し込む機構が必要です。

レベル100までやってみた感想ですけど、総合的には面白かったです。効率的な機構を考え付いたときが爽快です。個人的な面白さのピークは「何でも作れる機構」を作りレベル30くらいを突破する辺りでした。そのあとはコピペ感が強くなってやや盛り下がるのはシステム上仕方ないですね。

近々shapez2がリリースされる(今はearly access版)みたいですが、さらに複雑になっているようで買うかどうか微妙です。やると疲れるんで……息抜きには向いてないです。

メモ: 技術系の話はFacebookから転記しておくことにした。

編集者:すずき(2024/10/10 18:55)

コメント一覧

  • コメントはありません。
open/close この記事にコメントする



link もっと前
2024年10月21日 >>> 2024年10月8日
link もっと後

管理用メニュー

link 記事を新規作成

<2024>
<<<10>>>
--12345
6789101112
13141516171819
20212223242526
2728293031--

最近のコメント5件

  • link 21年9月20日
    すずきさん (11/19 01:04)
    「It was my pleasure.」
  • link 21年9月20日
    whtさん (11/17 23:41)
    「This blog solves my ...」
  • link 24年10月1日
    すずきさん (10/06 03:41)
    「xrdpで十分動作しているので、Wayl...」
  • link 24年10月1日
    hdkさん (10/03 19:05)
    「GNOMEをお使いでしたら今はWayla...」
  • link 24年10月1日
    すずきさん (10/03 10:12)
    「私は逆にVNCサーバーに繋ぐ使い方をした...」

最近の記事3件

  • link 23年4月10日
    すずき (11/15 23:48)
    「[Linux - まとめリンク] 目次: Linux関係の深いまとめリンク。目次: RISC-V目次: ROCK64/ROCK...」
  • link 24年11月6日
    すずき (11/15 23:47)
    「[Ubuntu 24.04 LTS on ThinkPad X1 Carbon Gen 12] 目次: Linux会社ではTh...」
  • link 24年11月11日
    すずき (11/15 23:26)
    「[Pythonのテストフレームワーク] 目次: Python最近Pythonを触ることが増えたのでテストについて調べようと思い...」
link もっとみる

こんてんつ

open/close wiki
open/close Linux JM
open/close Java API

過去の日記

open/close 2002年
open/close 2003年
open/close 2004年
open/close 2005年
open/close 2006年
open/close 2007年
open/close 2008年
open/close 2009年
open/close 2010年
open/close 2011年
open/close 2012年
open/close 2013年
open/close 2014年
open/close 2015年
open/close 2016年
open/close 2017年
open/close 2018年
open/close 2019年
open/close 2020年
open/close 2021年
open/close 2022年
open/close 2023年
open/close 2024年
open/close 過去日記について

その他の情報

open/close アクセス統計
open/close サーバ一覧
open/close サイトの情報

合計:  counter total
本日:  counter today

link About www.katsuster.net
RDFファイル RSS 1.0

最終更新: 11/19 01:04