notes
ToolsFibril can

fibril_can の使い方 (スキーマ YAML + vcan quickstart)

スキーマ YAML の最小構造、vcan でサンプルを動かす手順、bridge の主な ROS API と再プロビジョン方法

要点: スキーマ YAML には node / limits / types / instances の 4 セクション。fibril_can_example を vcan で立ち上げれば /example_node16/motor{0..3}/... が ROS 上に動的生成される。設定変更は ros2 param set、再組立は reprovision_node service。

準備 (vcan)#

sudo modprobe vcan
sudo ip link add dev vcan0 type vcan
sudo ip link set up vcan0

前提: Linux + ROS 2 Jazzy + libprotobuf-dev + yaml-cpp + ros_babel_fish。

サンプル起動#

ros2 launch fibril_can_example example_slave.launch.py

これで fcan_example_slave と bridge_node が両方 vcan0 で立ち上がる。スレーブは node_id=0x10 で名乗る。RUNNING に上がると Topic / Service / Param が生える。

動作確認#

# 生えている entity を見る
ros2 topic list
ros2 service list
ros2 param list

# feedback
ros2 topic echo /example_node16/motor0/state

# 指令
ros2 topic pub /example_node16/motor0/command \
  fibril_can_example_msgs/msg/MotorCommand \
  "{mode: 1, setpoint: 1.0, feedforward: 0.0}"

# service
ros2 service call /example_node16/motor0/set_mode \
  fibril_can_example_msgs/srv/SetMode "{mode: 1}"

# param (bridge が保持、スレーブ再起動時に PARAM_SET で再注入)
ros2 param set /fibril_can_bridge example_node16.motor0.kp 1.5

再プロビジョン (状態をやり直したい時)#

ros2 service call /fibril_can_bridge/reprovision_node \
  fibril_can_msgs/srv/ReprovisionNode "{node_id: 0x10}"

対象ノードの ROS entity を一旦破棄 → DISCOVER → ANNOUNCE → FRAME_DEFINE → START を実行。

フレーム配置の確認#

ros2 topic echo /fibril_can_bridge/communication_structure --once

transient_local QoS。どのフィールドがどの std_can_id のどこにいるかテキストで確認できる。(再) プロビジョン完了時に更新。

スキーマ YAML の最小構造#

node: example_node{i}      # {i} は起動時 node_id に置換
protocol: 1                # 現行 1

limits:
  max_frames: 16           # フレームスロット数 (既定 16)
  max_copy_entries: 128    # コピーエントリプール (既定 128)
  service_buffer: 0        # 分割転送バッファ、0 で無効化 (SINGLE のみ)
  service_reassembly: 1    # 同時組立数 (既定 1)
  # param_set_batch_bytes: PARAM_SET 1 要求の上限、0 で bridge 既定

types:
  MotorDriver:
    params:
      kp: { type: f32, default: 0.0 }
      max_current: { type: f32, default: 10.0, min: 0.0, max: 30.0 }
    topics:
      command:                       # m2s (master -> slave)
        dir: m2s
        fields:
          mode: u8
          setpoint: f32
          feedforward: f32
        ros: { type: fibril_can_example_msgs/msg/MotorCommand }
      state:                         # s2m
        dir: s2m
        period_us: 1000              # 既定周期 [μs]、0 or 省略でイベント送信
        fields:
          velocity: f32
          position: f32
        ros: { type: fibril_can_example_msgs/msg/MotorState }
    services:
      set_mode:
        request:  { mode: u8 }
        response: { accepted: bool }
        ros: { type: fibril_can_example_msgs/srv/SetMode }

instances:
  - { type: MotorDriver, max_count: 4, ns: "motor{i}" }

セクション別のポイント#

node#

  • ROS namespace のルート。{i} で node_id 置換 → 同じ FW を複数スレーブで走らせても namespace 分離できる

limits#

  • #define に落ちて RAM 使用量がビルド時確定
  • service_buffer = 0 は 要求 64B / 応答 63B の SINGLE のみ対応、大きい service には 128〜1024 を設定 (SPEC 上限 1024)

types#

  • スカラ型: bool, u8/i8, u16/i16, u32/i32, u64/i64, f32, f64
  • 固定長配列: gyro: { type: f32, len: 3 }
  • Topic 方向: m2s or s2m
  • period_us: s2m 周期送信、m2s では指定しない
  • Field 単位のヒント: period_us 上書き、enabled: false で当該フィールドを frame に置かない

instances#

  • max_count を書く: 静的確保、その上限分のアリーナ事前確保
  • max_count / count 両方書かない: heap / unbounded として静的検査だけ通し、実数は runtime の instance_counts で決定
  • ns: "motor{i}" の {i} はインスタンス番号 (0..count-1) に展開

bridge が保持する状態#

  • param 値: スレーブ再起動しても bridge が復元 (PARAM_SET で再注入)
  • frame 配置: communication_structure トピックに publish
  • schema blob キャッシュ: 同じ ANNOUNCE ハッシュなら SCHEMA_READ をスキップ

命名の展開規則#

YAML の階層 / は:

出力先展開
C 側シンボル__ (例: motordriver_param_velocity__kp)
ROS topic / service/ そのまま (path separator)
ROS parameter. に置換 (例: example_node16.motor0.kp)

関連#

最終更新:

On this page