Rerun.io 核心概念中文指南
依據官方文件 https://rerun.io/docs/concepts 整理。適合初次使用 Rerun 的開發者快速建立心智模型。
一、Rerun 是什麼
Rerun 是一套多維感測資料的視覺化平台,特別適合機器人、電腦視覺、感測器融合等場景。你在程式中記錄資料(log),Rerun Viewer 就能即時或事後播放這些資料的時序變化。
核心工作流程:
你的程式 —rr.log()→ Recording → Viewer(即時或檔案)
二、Recording(記錄)
Recording 是 Rerun 中資料的基本容器,對應一個 .rrd 檔案或一條串流。
初始化方式(Python):
import rerun as rr
rr.init("my_app") # 建立一個 recording,app ID 為 "my_app"
rr.connect_tcp() # 串流到本地 Viewer
# 或
rr.save("output.rrd") # 存成檔案,事後用 Viewer 開啟關鍵概念:
application_id:決定哪個 Blueprint(版面配置)會被套用recording_id:若多個 process 共用同一個 recording ID,它們的資料會合併成單一邏輯 recording,方便分散式記錄
三、Entity 與 Component(實體與元件)
這是 Rerun 資料模型的核心,類似遊戲 ECS 的前兩層。
Entity:具名容器,用路徑字串表示(例如 "robot/arm/gripper")
Component:掛在 Entity 上的實際資料(例如位置、顏色、影像像素)
rr.log("camera/image", rr.Image(img)) # Entity 路徑 + Archetype
rr.log("robot/joints", rr.Points3D(positions)) # 一個 log 呼叫可掛多個 componentArchetype 是便利包裝:rr.Points3D(...) 會自動拆解成 Position3D + Color + Radius 等 component。
四、Entity Path 層級
路徑用 / 分隔,形成樹狀結構,類似檔案系統:
world/
robot/
base_link
arm/
joint1
gripper
camera/
image
detections/
points
實用規則:
- 不需要顯式建立父路徑,Rerun 自動處理
- Transform(座標變換)、Annotation Context 會沿路徑繼承
- Blueprint 可以選取某個路徑及其所有子孫一起顯示
五、Timelines(時間軸)
Rerun 支援多條時間軸,讓你從不同時間維度瀏覽資料。
預設時間軸(自動建立):
log_tick:log 呼叫的順序編號log_time:系統時鐘時間
自訂時間軸:
rr.set_time("frame_idx", sequence=42) # 序列型(frame 編號)
rr.set_time("sensor_time", timestamp=ts_ns) # 時間戳(奈秒 Unix epoch)
rr.log("lidar/points", rr.Points3D(pts)) # 這筆資料同時掛在兩條時間軸Static 資料: 用 rr.log(..., static=True) 記錄的資料不屬於任何時間點,對所有時間軸都可見(適合場景 mesh、座標系定義等)。
六、Transforms(座標變換)
Rerun 原生支援 3D 座標系轉換,對機器人場景特別重要。
方法一:路徑層級隱含 transform(最常用)
rr.log("world/robot/camera",
rr.Transform3D(translation=[0.1, 0, 0.5],
rotation=rr.RotationQuat([0,0,0,1])))
rr.log("world/robot/camera/image", rr.Image(img))此時 camera 相對於 robot 的位姿由 Transform3D 定義,Viewer 會自動換算到 world frame。
方法二:Named Coordinate Frame(拓撲可隨時間變化)
rr.log("robot_base", rr.CoordinateFrame(frame="base_link"))
rr.log("camera_frame",
rr.Transform3D(parent_frame="base_link",
child_frame="camera_link", ...))Pinhole 相機模型(投影):
rr.log("camera", rr.Pinhole(focal_length=..., width=..., height=...))
rr.log("camera/image", rr.Image(img))七、Blueprint(視覺化版面)
Blueprint 控制 Viewer 要顯示什麼、用什麼方式呈現,和 recording(資料)分開管理。
用 Python 程式生成 Blueprint:
import rerun.blueprint as rrb
blueprint = rrb.Blueprint(
rrb.Horizontal(
rrb.Spatial3DView(origin="world"),
rrb.Vertical(
rrb.Spatial2DView(origin="camera/image"),
rrb.TimeSeriesView(origin="robot/joints"),
)
)
)
rr.send_blueprint(blueprint)View 類型:
Spatial3DView:3D 場景Spatial2DView:2D 影像/平面TimeSeriesView:時序折線圖BarChartView、TextLogView、MapView等
八、常見應用模式
機器人感測器記錄
rr.init("robot_demo")
rr.connect_tcp()
for frame in sensor_stream:
rr.set_time("frame", sequence=frame.idx)
rr.log("lidar/points", rr.Points3D(frame.lidar))
rr.log("camera/rgb", rr.Image(frame.rgb))
rr.log("robot/pose", rr.Transform3D(translation=frame.pos,
rotation=frame.quat))離線分析(先存檔再看)
rr.init("analysis_run")
rr.save("/tmp/run_001.rrd")
# ... 跑完資料記錄 ...
# 之後用 `rerun /tmp/run_001.rrd` 開啟多 process 分散式記錄
recording_id = "shared-run-001"
# process A
rr.init("robot_app", recording_id=recording_id)
# process B(另一台機器或另一個 node)
rr.init("robot_app", recording_id=recording_id)
# Viewer 會自動合併兩者的資料九、Chunk 與 Apache Arrow 內部儲存機制
什麼是 Chunk?
Chunk 是 Rerun 資料架構的核心儲存單位(自 v0.18 起全面採用)。每一個 Chunk 是一張 Apache Arrow 編碼的行欄式(column-oriented)資料表,包含:
| 欄位類型 | 說明 |
|---|---|
| Control column | 全域唯一 Row ID |
| Time/index columns | 時間軸資料(如 log_tick、log_time、自訂 timeline) |
| Component columns | 各 component 的資料(如 Points3D:positions、Points3D:colors) |
每個 component column cell 對應一個 Component Batch(Rerun 的原子資料單位),包含一或多個 instance。
Apache Arrow 扮演的角色
Rerun 在底層使用 Apache Arrow 作為資料序列化與記憶體格式:
- Component 資料以 Arrow array 表示,跨語言(Python/C++/Rust)共享同一記憶體佈局
- Chunk 從 SDK 一路傳到 data store,再到 visualizer 和 GPU,全程零複製(zero-copy)
- 行欄式佈局讓高頻小訊號(tall column)和低頻大資料(如點雲 tensor,wide column)能混合在同一個 recording 中
# SDK 底層流程(自動發生):
# rr.log() → Arrow array → batcher 累積 → Chunk → 傳輸/儲存兩種資料輸入路徑
路徑一:rr.log()(行導向,適合即時記錄)
for i, pts in enumerate(frames):
rr.set_time("frame", sequence=i)
rr.log("lidar/points", rr.Points3D(pts))
# SDK 自動把每行資料打包成 Arrow array,累積後形成 Chunk- 自動加入
log_time、log_tick兩條時間軸 - Batcher 達到大小閾值或定期觸發才傳送
路徑二:rr.send_columns()(欄導向,適合批次/離線資料)
import numpy as np
import rerun as rr
times = np.arange(0, 64)
scalars = np.sin(times / 10.0)
rr.send_columns(
"scalars",
indexes=[rr.TimeColumn("step", sequence=times)],
columns=rr.Scalars.columns(scalars=scalars),
)- 繞過 time context 和 micro-batcher,直接產生大 Chunk
- 不會自動加
log_time/log_tick,只包含你明確指定的時間軸 - 壓縮率更佳,ingestion 速度更快(benchmark: 比逐行 log 快 ~100x)
點雲序列(多時間步,不同點數):
rr.send_columns(
"points",
indexes=[rr.TimeColumn("time", duration=times)],
columns=[
*rr.Points3D.columns(positions=positions).partition(lengths=[2, 4, 4, 3, 4]),
*rr.Points3D.columns(colors=colors, radii=radii),
],
)partition(lengths=...) 告知 Rerun 每個時間步各自有幾個點,因為批次中點數不固定。
影像序列:
rr.send_columns(
"images",
indexes=[rr.TimeColumn("step", sequence=times)],
columns=rr.Image.columns(
buffer=images.view(np.uint8).reshape(len(times), -1)
),
)Chunk Compaction(壓縮優化)
Rerun 在 ingestion 時會自動把小 Chunk 合併成目標大小範圍內的大 Chunk。記錄完成後也可以用 CLI 手動優化:
rerun rrd compact --max-rows 4096 --max-bytes=1048576 my_recording.rrd效能數字參考(v0.18 benchmark)
- 225 萬筆 scalar 資料點:ingestion 速度提升 ~100x,記憶體 overhead 降低 ~35x
- v0.18 後,百萬時間點規模為「完整支援」等級
十、快速上手 Checklist
pip install rerun-sdkrr.init("app_name")+rr.connect_tcp()或rr.save("file.rrd")- 設計你的 Entity Path 層級(建議對齊你的座標系樹)
- 在每個時間步呼叫
rr.set_time(...)再rr.log(...) - 若有座標系關係,用
rr.log(..., rr.Transform3D(...))定義 - 用 Blueprint API 或 Viewer GUI 調整版面
參考連結
- 官方概念文件:https://rerun.io/docs/concepts
- Chunks 概念:https://rerun.io/docs/concepts/logging-and-ingestion/chunks
- send_columns 指南:https://rerun.io/docs/howto/logging-and-ingestion/send-columns
- Column Chunks 部落格(v0.18):https://rerun.io/blog/column-chunks
- Python API:https://ref.rerun.io/docs/python
- Python Columnar API:https://ref.rerun.io/docs/python/dev/common/columnar_api/
- Apache Arrow 欄式格式:https://arrow.apache.org/docs/format/Columnar.html
- 範例集:https://rerun.io/examples