@seyond-perception/pcv-replay
v0.1.1
Published
`@seyond-perception/pcv-replay` 是基于 Three.js 的 PS32 2.0 点云回播组件。组件负责创建 Three.js 场景、连接点云 WebSocket 和控制 WebSocket、解析动态点云与 box 数据,并提供播放、暂停、上一帧、下一帧、跳转和雷达切换能力。
Readme
@seyond-perception/pcv-replay
@seyond-perception/pcv-replay 是基于 Three.js 的 PS32 2.0 点云回播组件。组件负责创建 Three.js 场景、连接点云 WebSocket 和控制 WebSocket、解析动态点云与 box 数据,并提供播放、暂停、上一帧、下一帧、跳转和雷达切换能力。
实现方式
组件由 createPcvReplay() 创建实例。调用方只需要提供一个用于挂载 canvas 的容器 id、点云 WebSocket 地址,以及可选的 control WebSocket 地址。
内部主要流程:
- 创建 Three.js
scene、renderer、camera和OrbitControls。 - 连接点云 WebSocket,接收 PS32 2.0 二进制帧。
- 解析 PS32 wrapper、header、payload:
- 动态点云:
type=1且topic=101 - box:
type=3且topic=110
- 动态点云:
- 点云 payload 使用 Three.js
DRACOLoader解码。 - control 首包读取
total、active_lidar和可选flatten拉平矩阵。 - 如果存在
flatten,点云 position 会先乘以该 4x4 矩阵再缓存和渲染。 - 点云和 box 都按帧缓存,渲染时以当前动态点云时间戳查找最近的 box。
- 当前播放帧使用 PS32 header 中的
replayIndex,从 0 开始。
基本使用
import { createPcvReplay } from "@seyond-perception/pcv-replay";
const replay = createPcvReplay({
containerId: "pcv-replay",
websocketUrl: "ws://host/ws/pointcloud",
controlWebsocketUrl: "ws://host/ws/control",
theme: "dark",
config: {
box: {
showHeading: false,
showId: false,
},
control: {
autoRequest: true,
initialFrameIndex: 0,
},
},
});HTML 容器示例:
<div id="pcv-replay" style="width: 100%; height: 100%;"></div>组件会在容器中创建并挂载 WebGL canvas。调用方需要保证容器存在且有明确尺寸。
入参
PcvReplayOptions
interface PcvReplayOptions {
containerId: string;
websocketUrl: string;
controlWebsocketUrl?: string;
decoderPath?: string;
theme?: "dark" | "light";
config?: PcvReplayConfig;
}字段说明:
containerId:必填,用于创建 canvas 的 DOM 容器 id。websocketUrl:必填,PS32 2.0 点云/box 数据 WebSocket 地址。controlWebsocketUrl:可选,回播控制 WebSocket 地址。需要自动请求帧、跳转、切换雷达时应传入。decoderPath:可选,Draco decoder 文件路径。默认使用包内draco/目录。theme:可选,dark或light,默认dark。config:可选,组件配置。
PcvReplayConfig
interface PcvReplayConfig {
theme?: "dark" | "light";
box?: {
showHeading?: boolean;
showId?: boolean;
};
control?: {
autoRequest?: boolean;
initialFrameIndex?: number;
playbackFps?: number;
prefetchThreshold?: number;
requestRangeAction?: string;
requestSize?: number;
};
}默认配置:
{
theme: "dark",
box: {
showHeading: false,
showId: false,
},
control: {
autoRequest: true,
initialFrameIndex: 0,
playbackFps: 10,
prefetchThreshold: 10,
requestRangeAction: "replay",
requestSize: 30,
},
}control 协议
组件连接 control WebSocket 后,期望后端先返回状态包:
{
"total": 411,
"active_lidar": 1,
"flatten": "1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1"
}字段说明:
total:总帧数。帧号范围通常是0..total-1。active_lidar:当前激活雷达 id。flatten:可选,4x4 拉平矩阵字符串,按行主序解析。
请求帧范围时,组件发送:
{
"action": "replay",
"payload": {
"start": 200,
"end": 229
}
}默认一次请求 30 帧。requestRangeAction 可修改 action 名称。
切换雷达时,组件发送:
{
"action": "change_lidar",
"payload": {
"lidar_id": 1,
"staticMapping": false
}
}实例能力
createPcvReplay() 返回 PcvReplayInstance。
常用属性:
scene:Three.jsScene。renderer:Three.jsWebGLRenderer。camera:Three.jsPerspectiveCamera。controls:Three.jsOrbitControls。connected:点云 WebSocket 是否连接。controlConnected:control WebSocket 是否连接。stats:统计信息。currentFrameIndex:当前内部渲染帧索引。totalFrames:control 返回的总帧数。activeLidar:control 返回的当前雷达 id。
常用方法:
replay.play();
replay.pause();
replay.nextFrame();
replay.previousFrame();
await replay.jumpToFrame(200);
await replay.changeLidar(1, false);
replay.updateConfig({ theme: "light" });
replay.resize();
replay.dispose();帧信息:
const progress = replay.getPlaybackFrameProgress();
// {
// currentFrame: 200,
// totalFrames: 411,
// dynamicFrameIndex: "24174"
// }
const dynamicInfo = replay.getLatestDynamicPointFrameInfo();
const boxInfo = replay.getLatestBoxFrameInfo();currentFrame 来自动态点云 header 中的 replayIndex,从 0 开始。页面如果想显示业务帧号,应直接展示该值;如果想显示第几张,可自行 +1。
已包含功能
- PS32 2.0 wrapper/header 解析。
- 动态点云 topic 过滤,只显示动态点云。
- Draco 点云解码。
- intensity 颜色映射,支持 dark/light 主题。
- control 首包读取总帧数、当前雷达和拉平矩阵。
- 点云拉平矩阵变换。
- box 解析和显示。
- box 类型配色。
- box heading 和 id 显示开关。
- box 与点云按时间戳最近匹配。
- 前端固定帧率播放,默认 10 FPS。
- 暂停、播放、上一帧、下一帧。
- 跳转到指定 replayIndex。
- 跳转后缺失帧自动按方向请求。
- 雷达切换。
- 实例销毁和资源释放。
注意事项
containerId对应 DOM 必须在调用createPcvReplay()前存在。- 容器需要有明确宽高,否则 canvas 可能不可见。
- 点云 WebSocket 应返回 PS32 2.0 二进制数据。
- 动态点云当前只接收
topic=101。 - box 当前只接收
topic=110。 flatten矩阵按行主序字符串解析。dispose()应在页面卸载或组件销毁时调用,避免 WebSocket、WebGL 和 Draco 资源泄漏。
目录结构
src/
replay.ts
index.ts
cache/
config/
layer/
protocol/
scene/
types/
ws/职责说明:
cache/:点云和 box 帧缓存。config/:默认配置、主题和颜色映射。layer/:Three.js 点云和 box 图层。protocol/:PS32 2.0 和 flatten 矩阵解析。scene/:Three.js scene、camera、renderer、controls。types/:公开类型定义。ws/:点云和 control WebSocket 管理。
