箱庭PDUアーキテクチャ(その4:ブリッジ編)


箱庭ブリッジを最初に考えたのは、忘れもしない、
高瀬先生と細合さんと、
箱庭のブリッジ構想を検討していた時でした。

当時、Zenohにハマっていたこともあり、
「箱庭の通信層はZenohで統一できるんでは?」
っていう夢物語を語っていました。

ちなみに、このあたりの記事で、実証実験の広報してました(わすれてた)。

箱庭ブリッジは奥が深い。

あの当時は、とりあえず、箱庭のシミュレーションの世界をZenohを通して、ROSと繋げる。
その一点で技術開発していたなと、しみじみと思い返されます(若かった)。

あれから、思い返せば、もう2年も経つんですね。

いろんな箱庭ブリッジってのを作りました。

はい、Zenohですべてを統合する。
無理ゲーだとおわかりました。

箱庭が扱いたい技術領域は、

  • ドローンのMAVLINK通信
  • WebブラウザやゲームアプリでのWebsocket通信
  • AR連携とか
  • :

いろんなバリエーションがあるんです。

当然、その当時(2024年)は、Zenohが対応しきれていないプログラミング言語もあったし、
たとえば、UnityでZenoh動かすとかね。

そんなの、いちいちやってられない。

で、結局は、箱庭のデモ特化型の「箱庭ブリッジ」つくりました。

「まー、現実はそんなもんなんかなー」って

半分、遠い夕日を細い目で見ながら、
そんな気分で作っていました。

ちょっと俯瞰して眺めてみるタイミングがきました。

箱庭の開発やっているとですね、そういう、技術的な泥臭さを色々よこに置きながら、
あるとき、それらを、まるで、
「おもちゃ箱から、ガラガラとあさって、眺めるように」
そう、俯瞰して、みる時期っていうのが来るんですよね。

そして、箱庭エンドポイントの設計が終わったときに、
エンドポイントは
全ての通信プロトコルを包含している。
ZenohもWebSocketも、
ぜんぶ同じ枠組みに収まっている。

…ってことは。

そのエンドポイントを、
転送設定して、
左から右に流すだけ。

それだけなんじゃない?!

そう気づいちゃったんです。

箱庭ブリッジを再設計してみた。

これが、今の箱庭ブリッジの設計です。

箱庭ブリッジは、通信を行いません。
エンドポイントが持つ通信能力を前提に、
「どのPDUを、いつ、どこへ流すか」だけを定義します。

ここで、もうひとつ大きな気づきがありました。

PDU の転送は、必ずしも
「1 対 1」である必要はない、ということです。

あるエンドポイントから出た PDU を、
複数のエンドポイントへ同時に流す(fan-out)。
シミュレーションの世界では、これはむしろ自然な振る舞いでした。

そしてもうひとつ。

転送において本当に重要なのは、
通信プロトコルではなく、時間的な振る舞いでした。

  • 更新された瞬間に即座に流す immediate
  • 帯域や負荷を意識して間引く throttle
  • 一定周期でまとめて流す ticker

箱庭ブリッジが扱うのは、
「どう送るか」ではなく、
「いつ、どう振る舞うか」。

fan-out と転送ポリシー。
この二つを明示的に切り出したことで、
箱庭ブリッジは、単なる通信の仲介ではなく、
PDU の時間的な流れを記述するコンポーネントになりました。

ちなみに。

そしてもうひとつ、大事な整理があります。

NAT 越えは、Zenoh の専売特許ではありません。

箱庭ブリッジの設計では、
通信はすべてエンドポイントが担当します。

つまり、

  • TCP で TCP をつなぐ
  • UDP から TCP へ(その逆もできる)
  • WebSocket で外に出る
  • 必要なら Zenoh を使う

どれも、同じ枠組みの中で成立します。

箱庭ブリッジが定義するのは、
通信経路ではなく、転送の関係性。

だから、
「NAT 越えが必要なら、その区間を エンドポイントで切り替えればいい」
それだけの話になります。

Zenoh が必要なのではなく、
“選べる”ことが重要だった。

実装してみた。

まだ、絶賛実装中ですが、箱庭ブリッジは、hakoniwa-pdu-bridge-core という名前に変えて、
以下のリポジトリで公開しています。

箱庭ブリッジって、要するに、
「PDU の転送」なんですよね。
だから、名前に pdu を入れました。

そして、最後に core を付けたのには、実は理由があります。

これは、
箱庭コンダクターへの布石でもあるからです。

箱庭ブリッジそれ自体は、
単体のツールではなく、
ライブラリとして使える形である必要がある。

そんな気づきが、ここでありました。

……この話を始めると長くなるので、
今回はここでは省略します。

あとねー。

さらに、箱庭PDUブリッジ(ここからネーミング変えます)は、箱庭PDUエンドポイントと同じように、jsonで設定できるようにしたんですよ。

{
    "version": "2.0.0",
    "time_source_type": "virtual",
    "transferPolicies": {
        "immediate_policy": { "type": "immediate" }
    },
    "nodes": [
        { "id": "node1" },
        { "id": "node2" }
    ],
    "endpoints_config_path": "endpoints.json",
    "wireLinks": [
        { "from": "epA_dst_wire", "to": "epB_src_wire" }
    ],
    "pduKeyGroups": {
        "pdu_group_pos": [
            { "id": "Drone.pos", "robot_name": "Drone", "pdu_name": "pos" }
        ]
    },
    "connections": [
        {
            "id": "node1_conn",
            "nodeId": "node1",
            "source": { "endpointId": "epA_src" },
            "destinations": [ { "endpointId": "epA_dst_wire" } ],
            "transferPdus": [ { "pduKeyGroupId": "pdu_group_pos", "policyId": "immediate_policy" } ]
        },
        {
            "id": "node2_conn",
            "nodeId": "node2",
            "source": { "endpointId": "epB_src_wire" },
            "destinations": [ { "endpointId": "epB_dst" } ],
            "transferPdus": [ { "pduKeyGroupId": "pdu_group_pos", "policyId": "immediate_policy" } ]
        }
    ]
}

詳細は省略しますが、
既存の箱庭 PDU エンドポイントの JSON 設定を参照しつつ、
箱庭 PDU ブリッジでは、転送設定だけを記述する形にしています。

通信の定義はエンドポイントに任せ、
ブリッジは「どう流すか」だけを書く。

……この分離、

「イケてません?!」

つづく。


“箱庭PDUアーキテクチャ(その4:ブリッジ編)” への1件のフィードバック

  1. […] 前回(その4)について、「少し難しかった」という感想もいただきました。これはもっともで、いきなり「ブリッジ」や「転送ポリシー」といった言葉が出てくると、全体像の絵がない状態では消化不良になりやすいからです。(すみません、ぶっ飛ばして書きました。ごめん、ごめん…) […]

トップへ戻る