Files
opendance-android/tasks/004-keypoint-serializer.md
T
zijunchiang 264786134c docs: 新增「初次部署(从零跑起来)」;去混淆字符与真实内网信息
- README.md / README.txt 新增初次部署章节:前置条件(JDK 17 / SDK 34 / Gradle 8.9)、
  获取代码与本地配置(local.properties 不入仓)、Debug/Release 构建、装到手机与相机权限、
  连接配置(只连 Windows 客户端,默认 8765 / /pose)、第一次跑通、自检清单、常见问题
- 单测数量按实际(30 项)修正
- 三库同源契约:':=' 写法修回、去掉真实 MariaDB 版本串
- 全文去除易被 Gitea 判为「模棱两可 Unicode」的字符
- 本机 JDK 路径与内网示例地址改占位符 / RFC 5737 文档网段
2026-09-15 21:33:27 +08:00

75 lines
2.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# T-AND-004 33 点 -> 239 字节帧
- **状态**:done
- **依赖**:T-AND-003(数据结构)、T-AND-001
## 目标
把 33 点关键点按冻结契约序列化为 239 字节二进制帧。
## load
```
DSH.md
contracts/websocket-keypoints.md # 锚点:2 二进制帧(冻结)
contracts/skeleton-topology.md # 锚点:1 33 点、4 坐标系
app/src/main/java/com/opendance/studio/model/KeypointFrame.kt
app/src/main/java/com/opendance/studio/model/SkeletonTopology.kt
```
## 帧布局(契约冻结)
```
偏移 长度 字段
0 2 magic u16 = 0x4F44 ('OD'),小端序 -> 字节序为 44 4F
2 1 version u8 = 1
3 1 flags u8 bit0 镜像 | bit1 低置信度 | bit2 上半身
4 4 frame_id u32 LE
8 231 keypoints 33 × 7B:s16 x, s16 y, s16 z, u8 conf
合计 239
```
## ★ 金标准字节向量测试
本任务的核心验收不是「函数跑通了」,而是**与另两端逐位一致**。
测试 `KeypointFrameTest.goldenVectorMatchesWebImplementation` 使用由
`opendance-web` 已通过验收的 TypeScript 实现产出的 239 字节金标准向量:
```bash
# 重新生成金标准向量(在 opendance-web 仓库内)
cd opendance-web/web-server && npm run build
node -e "
const { encodeBinaryFrame } = require('./dist/preprocess/keypoint-codec.js');
const points = [], conf = [];
for (let i = 0; i < 33; i++) {
points.push([(i%33)/32, 1-(i%33)/32, ((i%7)-3)/10]);
conf.push(i%2===0? 1.0: 0.5);
}
const buf = encodeBinaryFrame(42, points.map((p,i)=>[...p,conf[i]]), 0b101);
console.log(buf.toString('hex'));
"
```
固定输入:`xs = (i%33)/32`、`ys = 1-(i%33)/32`、`zs = ((i%7)-3)/10`、
`confidence = i%2==0? 1.0: 0.5`、`frameId = 42`、`flags = 0b101`。
## 关键实现
- `ByteBuffer.order(LITTLE_ENDIAN)`,避免手动移位出错
- 定点换算 `round(v × 32767)` 并 `coerceIn(-32768, 32767)`
- 置信度 `round(v × 255)`,阈值 0.5 含端点(`>=`)
- 输入超范围时裁剪而非抛异常(相机抖动可能产生轻微越界值)
- 并行 FloatArray 存储,30 FPS 循环内零对象分配
## 验收
```bash
./gradlew testDebugUnitTest
```
19 项单元测试全部通过,含:
常量与契约一致、金标准向量逐位一致、编解码往返精度、错误长度/magic/版本拒绝、
极值不溢出、超范围裁剪、低置信度标志计算、镜像 x 还原、拓扑父链表无环、
骨架连线索引合法。