mcpField
R
rerun-blueprint

rerun-blueprint

github.com/rerun-ioデータ・データベース11.7k132 回インストール今日更新
リポジトリ

rerun-blueprint について

rerun-blueprintは、Rerunの記録やテーブルの表示方法を設定するスキルです。データを確認してビューとレイアウトを設計し、スクリーンショットを見ながらブループリントを調整します。

主な機能

  1. 01記録のビューとレイアウト設定
  2. 02テーブル列、フィルター、カードの設定
  3. 03エンティティとアーキタイプに応じたビュー選択
  4. 04ビューの配置と表示範囲の指定
  5. 05スクリーンショットによる調整

活用シーン

  1. 01記録データの複数ビューを設計
  2. 02データセットの列や行フィルターを調整
  3. 03空の空間ビューやレイアウトの問題を調査

MCP 対応

viewer MCPでrerun_get_blueprintを使ってブループリントを読み、rerun_set_blueprintで書き込みます。テーブルスキーマの確認とテーブル設定の更新にも対応します。

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/rerun-io/rerun --skill rerun-blueprint

インストール後、Claude Code で/rerun-blueprintを入力して読み込まれたか確認します。

詳細

Rerun ブループリント

**ビューアーの見た目を変えるには、ブループリントを変更します。**これは、記録のレイアウト、ビューとそのプロパティ、テーブルの列、行フィルター、カードに当てはまります。ビューアーのメニューをクリックして変更しないでください。ビューアー MCP では、低レベルのクリックツールではなく、rerun_get_blueprint と rerun_set_blueprint を使ってブループリントを読み書きします。

ブループリントは記録の表示方法を決め、記録は何が存在するかを決めます。 データを読み、最初のレイアウトを設計し、ひと目で内容がわかるまでスクリーンショットを見ながら調整します。コンストラクターは確認できます(dir(rrb)、 help(rrb.Spatial3DView))。このスキルでは、推測できない部分を説明します。import rerun.blueprint as rrb としてインポートします。

テーブル

データセットのセグメントテーブルとカタログテーブルには、それぞれ独自のテーブルブループリントがあり、記録のブループリントとは別です。表示する列、その順序と名前、行フィルター、行をテーブルとカードのどちらで表示するかを設定します。テーブルの見た目を整えるよう依頼された場合は、このブループリントを書き換えます。

次の例では、2 つの列を非表示にし、別の 3 つの列を先頭に表示します。列の一覧にある列が先頭に並び、それ以外の列はデフォルトの順序と表示設定を維持します。

blueprint = rrb.TableBlueprint(
    table_layout=rrb.table.TableLayout(
        columns=[
            rrb.table.Column("recording link"),
            rrb.table.Column("property:episode:current_task", name="Task"),
            rrb.table.Column("property:episode:success"),
            rrb.table.Column("property:episode:ext1_cam_serial", visible=False),
            rrb.table.Column("property:episode:ext2_cam_serial", visible=False),
        ],
    ),
)
blueprint.save("my_app", path)
dataset.register_blueprint(path.as_uri(), segment_table=True)

Column には、ヘッダー名ではなく、property:episode:uuid のようにテーブル上の列名を指定します。登録すると、そのテーブルを開くすべてのユーザーに対するデフォルトになります。また、サーバーが path を読み取れる必要があります。

行フィルターは SQL 式で、文字列ごとに 1 つ指定し、すべての式が行に対して真である必要があります。例:rrb.TableBlueprint(filters=["\"task\" ILIKE '%pick%'", '"duration" > 10'])。列名には二重引用符、文字列には一重引用符を使います。リスト列には any_match("column", x -> …) を使います。

ビューアー MCP では、画面上のテーブルを直接変更できます。 rerun_get_table_schema で列名を確認し、{"table": {}} を指定した rerun_get_blueprint でテーブルブループリントを読み取り、{"table": {}} を指定した rerun_set_blueprint で置き換えます。フィルターが無効な場合、rerun_set_blueprint はエラーを返します。列のエントリーは /table/layouts/table/columns/<column name> にあり、名前に含まれる各 : とスペースは \: と \ にエスケープします。JSON ではそれぞれ \\: と \\ と記述します。JSON の具体例は MCP docs をご覧ください。カードやセグメントプレビューも含めた Python API 全体については、テーブルレイアウトとセグメントプレビューを設定する をご覧ください。

1. データを読む

まず、すべての (entity_path, archetype) の組み合わせを列挙します。archetype はビューを選び、entity path はその対象範囲を指定します。データセットの場合は(rerun-catalog-queries を参照):

for c in dataset.schema().component_columns():
    print(c.entity_path, c.archetype, c.component_name)

ローカルの記録の場合は、RrdReader でストリーミングし、各チャンクから entity_path と archetype を読み取ります(rerun-chunk-processing を参照)。

データセットのスキーマだけでは、ビューに表示できるすべてのエンティティはわかりません。アセットとは URDF ロボットメッシュのような静的データで、ビューアーはこれをすべてのセグメントに適用しますが、セグメントエンティティには表示されません。rerun_get_dataset_schema が entities と並べて asset_ids を表示する場合は、rerun_get_dataset_assets_schema を呼び出して各アセット内のエンティティを取得し、2D ビューと 3D ビューのどちらを選ぶか、またはプレビューを選ぶ前に読み取ります。たとえば、asset_ids: ["urdf-model-left", "urdf-model-right"] は、ロボットモデルを Spatial3DView に表示できることを意味します。

2. アーキタイプをビューに対応付ける

アーキタイプの種類ビュー
Points2D, Image, EncodedImage, Boxes2D, LineStrips2D, Pinhole projectionsSpatial2DView
Points3D, Mesh3D, Boxes3D, LineStrips3D, Transform3D, Asset3DSpatial3DView
Scalars, SeriesLines, SeriesPointsTimeSeriesView
TextLog / TextDocument / BarChartTextLogView / TextDocumentView / BarChartView
Tensor, DepthImage(ヒートマップ)TensorView
GeoPoints, GeoLineStringsMapView
GraphNodes, GraphEdgesGraphView
表形式データ/カタログデータDataframeView

Asset3D や URDF メッシュなどのアセットエンティティは、Spatial3DView に配置します。

3. エンティティをビューにまとめる

このステップでは、どのエンティティを同じビューに配置するかだけを決めます。サイズや配置は、スクリーンショットを確認しながら調整するもので、事前にルールとして決める必要はありません。

  • 共通のパスプレフィックスごとにまとめます。 共通のプレフィックス配下にあるエンティティは、通常、1つのビューにまとめます。エンティティごとにペインを作らないでください。生のメッセージエンティティが何十個もある場合は、それぞれ別のペインにするのではなく、1つの DataframeView にまとめるか、表示対象から外します。
  • 空間ビューごとに空間フレームは1つにします。 Transform3D ツリー全体は、共通の祖先を Spatial3DView の起点として、1つのビューに配置します。Pinhole カメラは、画像が投影を継承するよう、カメラを起点とする独自の Spatial2DView に配置します。
  • スカラーをまとめます。 1つのプレフィックス配下に多数の Scalars がある場合、それぞれ個別に配置するのではなく、プレフィックス全体を対象にした1つの TimeSeriesView にまとめます。値の範囲が合わない場合にのみ分割します。
  • column_shares/row_shares は、コンテナ内の子要素に対する相対的な重みです。 デフォルトでは均等です。スクリーンショットを見て調整します。

4. 構成する

コンテナ(Grid、Horizontal、Vertical、Tabs)にビューを配置します。フラットなビュー群には Grid をデフォルトとして使います。意図的に分割する場合はほかのコンテナを使い、同じ場所を取り合う選択肢(左/右/深度カメラなど)には Tabs を使います。必ず明示的に origin と name を設定してください。 origin のデフォルトは / で、ツリー全体が1つのビューに詰め込まれてしまいます(読みにくい塊になる主な原因です)。

blueprint = rrb.Blueprint(
    rrb.Horizontal(
        rrb.Spatial3DView(origin="/world", name="Scene"),
        rrb.Vertical(
            rrb.Spatial2DView(origin="/world/camera", name="Camera"),
            rrb.TimeSeriesView(origin="/sensors", name="Sensors"),
        ),
        column_shares=[3, 2],
    ),
    rrb.TextLogView(origin="/logs", name="Logs"),
    collapse_panels=True,
)

contents のデフォルトは "$origin/**" です。包含/除外ルールでビューの対象を絞り込みます。例:contents=["+ $origin/**", "- $origin/internal/**"]。プレフィックスのない行は包含ルールです。ワイルドカードは /** のみで(サブツリーに一致します)。最も具体的なルールが優先され、同じ具体性の場合は後のルールが優先され、一致するパスがない場合は除外されます。

座標フレーム。 空間ビューでレンダリングされるのは、対象フレームに対する位置を特定できるエンティティのみです。エンティティに記録された Transform3D/Pinhole はツリーに沿って合成されるため、origin を指定するだけで十分です。一方、名前付きフレーム(ROS/MCAP で一般的な CoordinateFrame(frame=...))は独立したフレームグラフに存在します。そのため、spatial_information=rrb.SpatialInformation(target_frame="<frame>") を使って、データが存在するフレームをビューの対象に指定します。空の3Dビューに「No transform path from <frame>…」というエラーが表示される場合は、これが原因です。origin="/" はルート tf#/ を対象にしますが、tf ツリーが実体化されていない場合、そこには何も接続されません。CoordinateFrame:frame の値を調べ、主要な3Dコンテンツが存在するフレームを対象に指定し、接続されていないフレーム内のエンティティを除外します。

5. スクリーンショットから反復する

ビューアーを起動して記録を一度読み込んだら、同じビューアーにブループリントを再送します。送信とスクリーンショットの組み合わせが、手軽な反復作業の1回分です。レンダリングして確認し、修正します。

ブループリントはストアの識別情報、つまりアプリケーション ID と記録 ID の両方でデータに紐付けられます。読み込んだ .rrd は独自の識別情報を保持しているため、ストリームはその rrd の値から構築してください(両方を設定してください。設定しない場合、recording_id はランダムな値がデフォルトになります)。どちらかが一致しないと、ビューアーはブループリントとデータを別々の記録として扱い、ブループリントは適用されません。

import time
import rerun as rr
import rerun.blueprint as rrb
from rerun.chunk import RrdReader
from rerun.experimental import ViewerClient

store = RrdReader("segment.rrd").recordings()[0]  # the rrd's application id + recording id

with ViewerClient.spawn(headless=True, port=9879) as viewer:
    rec = rr.RecordingStream(store.application_id, recording_id=store.recording_id)
    rec.connect_grpc(url=viewer.url)
    rec.log_file_from_path("segment.rrd")

    def shot(blueprint, path):
        rec.send_blueprint(blueprint, make_active=True, make_default=True)
        time.sleep(2)  # let the import finish and a frame render; bump if a view is blank
        viewer.save_screenshot(path)  # view_id=view.id for a single view

    shot(blueprint_v1, "bp_v1.png")
    # Read bp_v1.png, revise, send the next one into the same viewer.
    shot(blueprint_v2, "bp_v2.png")

完成したブループリントを組み込むには、rr.init / spawn / connect_grpc / save に default_blueprint= を渡すか、notebook_show に blueprint= を渡します。

注意点

  • DataframeView はクエリがないと「タイムラインが不明」と表示されます: query=rrb.archetypes.DataframeQuery(timeline="<timeline>", apply_latest_at=True)。
  • ビューが空白に戻る場合、インポーターの処理がまだ終わっていない可能性があります(待機時間を延ばしてください)。または、カーソルがデータより前にある可能性があります(rrb.TimePanel(play_state=rrb.components.PlayState.Following) を追加してください)。
  • rrb ビューと ViewerClient(rerun.experimental)は不安定です。コンストラクターの引数が拒否された場合は、help() を確認してください。

関連項目

  • rerun-data-model — エンティティ、アーキタイプ、タイムライン。
  • rerun-catalog-queries — データセット内のエンティティを列挙します。

コメント