notes
ToolsFibril can

fibril_can Web マスター (TypeScript / gs_usb)

ROS 2 を介さずにブラウザ・Node から gs_usb 経由で fibril_can スレーブを駆動する TS 実装。C++ bridge と並列の独立コードベース

要点: fibril_can_web は C++ の fibril_can_bridge と同じワイヤプロトコルを TypeScript で並列実装した master 経路。ブラウザや Node から gs_usb 互換の USB-CAN デバイス (Web Serial / WebUSB) で CAN FD を直接読み書きする。ラボ用デバッグ UI、教育用ダッシュボード、Web 製御コンソール用途。

パッケージ構成 (pnpm monorepo)#

パッケージ種別中身
@fibril/can-transportライブラリITransport 抽象。raw CAN frame TX/RX のみ、fibril_can セマンティクスなし
@fibril/can-transport-gsusbライブラリgs_usb 互換の ITransport 実装 (Web Serial / WebUSB)
@fibril/can-transport-mockライブラリプロセス内ループバック (test 用)
@fibril/can-coreライブラリTS 側のワイヤ+IR 単一正本。protocol 定数 / Extended ID codec / scalar pack / DLC / 設定プレーン / schema 復号 / SHA-256 / 採番 / NodeAgent / MasterController / DataPlaneReceiver / ServiceClient / TypedService / TypedParam / SchemaIndex / frame_planner
apps/snifferReact applisten-only スニッファ UI
apps/masterReact appアクティブマスター UI。MasterController を駆動

依存方向:

transport ─▶ transport-gsusb / -mock
             │
             ▼
         @fibril/can-core
             │
             ▼
       apps/sniffer   apps/master

@fibril/can-core だけがワイヤ + IR を知る。transport はフレームだけ、apps は core の API を呼ぶだけ。C++ 側 fibril_can_core と対をなす二重実装で、両方が SPEC を独立に実装する。

クイックスタート (スニッファ、listen-only)#

cd fibril_can_web
pnpm install
pnpm dev:sniffer

Vite dev server → ブラウザで gs_usb デバイス選択 → bitrate 設定 → 接続。手動 schema.blob ロードで S→M Topic を std_id にピン止めしてフィールドを decode 表示。バスに送信しないので、他 master が走ってても安全。

クイックスタート (アクティブマスター UI)#

pnpm dev:master     # http://localhost:5174

gs_usb デバイス選択で MasterController が起動、以下を自動で回す:

  • start() 直後に 1 回 broadcast DISCOVER (前 master の残骸を一掃、initialDiscover: false で抑止)
  • MASTER_HEARTBEAT 周期送出 (既定 100ms)
  • ANNOUNCE / HEARTBEAT を受けたスレーブに対する NodeAgent 自動 spawn
  • spawn 後 defaultS2MFramePlan で S→M 全 Topic 購読の FRAME_DEFINE → START

broadcast DISCOVER は破壊的 (SPEC §5.11、受信スレーブの frame table wipe → UNPROVISIONED)。周期送出は既定 OFF (discoverPeriodMs: 0)。遅れて起動したスレーブは自身の起動時 spontaneous ANNOUNCE × 3 でほぼ拾える。補助的な再探索は UI の Discover ボタン。

UI の 8 タブ#

タブ内容
Overviewspawn 済みスレーブ一覧 (state バッジ / boot_id / schema_hash / HEARTBEAT 鮮度)、autostart トグル、Start ボタン
Schema選択スレーブの Topics / Services / Params (field 型 / wire size / default)
FramesFramePlan を 1 frame=1 card。std_id / dir / period、packed entries の byte レイアウト可視化
TopicsS→M ライブ値 (dict + rate Hz、10 Hz ポーリング) + M→S 定義。field 単位の on/off、Apply で FRAME_DEFINE 打ち直し
Servicesrequest エディタ → Call → response + status。Trigger 形は Call ボタンのみ
Paramsdefault 初期値の編集フォーム → Set → SVC_PARAM_SET の status / failedIndex
GraphsS→M 数値フィールドの multiselect + uPlot、30 Hz サンプル、window 5s〜3m
Raw CANtransport tee の 5000 件リングバッファ、fibril ext-ID を CFG ANNOUNCE node=0x10 seq=3 形式に decode

プログラム経由 (単体 NodeAgent)#

import { connectGsUsb } from '@fibril/can-transport-gsusb';
import { NodeAgent, MasterHeartbeatBroadcaster, defaultS2MFramePlan }
  from '@fibril/can-core';

const transport = await connectGsUsb({ bitrate: 1_000_000, dataBitrate: 5_000_000 });
await transport.open();

const heartbeat = new MasterHeartbeatBroadcaster(transport, 100);
heartbeat.start();

const agent = new NodeAgent({
  nodeId: 0x10,
  transport,
  framePlan: (schema, numbering) => defaultS2MFramePlan(schema, numbering),
  onState: (s) => console.log('state', s),
});
await agent.start();

// state.kind === 'running' 後に snapshot が読める
const snap = agent.snapshot!;
const setPid = snap.service<{kp: number}, {accepted: boolean}>('motor0/set_pid');
const r = await setPid.call({ kp: 1.5 }, { timeoutMs: 250 });

// param set は SVC_PARAM_SET (0xFD) 経由
await snap.param<number>('motor0/velocity/kp').set(2.0);

MasterHeartbeatBroadcaster の使い分け#

SPEC §5.11 の MASTER_HEARTBEAT を周期送出するだけの独立コンポーネント。NodeAgent には含まれていない。1 本の transport に複数 NodeAgent を載せるなら broadcaster は 1 つを全 agent で共有。

framePlan のカスタム#

defaultS2MFramePlan はスレーブが送る S→M Topic を全 field 購読するデフォルト。一部だけ購読したい / 周期を変えたいなら FieldRequest を直接組み立てて planFrames に渡す。

typed bindings は未着手#

schema.blob → TypeScript interface + path のリテラル型の generator は現状ない。TS 側は文字列 path で service / param を呼ぶ。将来やるなら @fibril/can-core から独立パッケージとして生やす想定。

bridge (C++) との使い分け#

場面推奨
ROS 2 スタックに載せるC++ fibril_can_bridge
ラボ用 GUI / ダッシュボードWeb master (apps/master)
一時的な観測Web sniffer (apps/sniffer)
CI / スクリプトから駆動Node で NodeAgent 直接

同じバスに両方の master を同時に載せない (DISCOVER / MASTER_HEARTBEAT が競合)。Web sniffer は listen-only なので併用可。

関連#

最終更新:

On this page