SDK 怎么用
G2-L 手套和 tracker 绑带定位器(全身)由 pico 动捕主机 融合成统一的 MocapFrame(1860 字节),再通过 UDP 发到你的电脑。这个文件夹里的 SDK 就是用来接收、解析、显示和二次开发这帧数据的。
本文件夹有 4 个包,各自的用法不一样,先按机器和语言选一个:
| 你的情况 | 用这个包 |
|---|---|
| Windows 电脑 | G2L_Mocap_SDK_1.0.0_windows_x86_64.zip |
| Linux PC / x86 工控机 | G2L_Mocap_SDK_1.0.0_linux_x86_64.tar.gz |
| ARM64 板(树莓派、Jetson、RK 系列等) | G2L_Mocap_SDK_1.0.0_linux_aarch64.tar.gz |
| 只写 Python,不想编译 | G2L_Mocap_SDK_Python_1.0.0.zip |
前三个是 C++ SDK(头文件 + 动态库/静态库 + 现成的可执行程序)。 Python 包是 纯 Python 实现,跨平台,三个平台共用一份 wheel,装完就能用。
- 先不写代码,直接跑包里的现成程序,确认能收到数据、画面能动。
- 确认没问题后,再把库接到你自己的程序里,循环读取 64 个关节位姿。
先选你现在要做的事
| 你现在的情况 | 往下看 |
|---|---|
| 刚解压,不知道这些文件是干什么的 | 包里每个文件 |
| 想先看数据对不对,还不写程序 | 第一步:先看画面 |
| 想在终端里逐条看关节数值 | 第二步:在终端看数据 |
| 想把数据录下来回放 | 录制与回放 |
| 要把数据接进自己的软件 | 接到自己的程序 |
| 想知道读出来的数是什么意思 | 读到的数据 |
| 跑不起来 / 收不到数据 | 常见问题 |
解压
Windows
在资源管理器里右键解压,或用命令行:
Expand-Archive -Path "G2L_Mocap_SDK_1.0.0_windows_x86_64.zip" -DestinationPath .解压后只得到一个目录 Forsense_Mocap_SDK_1.0.0_windows_x86_64,里层直接就是 bin、include、lib、demo、README.md。
Linux
tar -xzf G2L_Mocap_SDK_1.0.0_linux_x86_64.tar.gz # x86_64
tar -xzf G2L_Mocap_SDK_1.0.0_linux_aarch64.tar.gz # ARM64解压出来的目录是 Forsense_Mocap_SDK_1.0.0_linux_x86_64(注意和压缩包名字不同)。 本页后面的路径都相对这个目录。
Python
# 解压 G2L_Mocap_SDK_Python_1.0.0.zip
# 然后进入解压出来的 dist 目录(Windows 右键「解压全部」常会多套一层同名目录,
# 以能看到 forsense_mocap-1.0.0-py3-none-any.whl 的那一层为准)
pip install forsense_mocap-1.0.0-py3-none-any.whl需要 Python >= 3.8,无第三方依赖。这一步是必须的:第二步的 Python 版菜单和 forsense-recv 命令都依赖它,不装会报 No module named 'forsense_mocap'。
包里每个文件
C++ SDK(Windows / Linux x86_64 / Linux aarch64 结构一致)
Forsense_Mocap_SDK_1.0.0_linux_x86_64/
├── README.md 包内说明书
├── include/forsense/ 公共头文件(二次开发用)
│ ├── protocol/ 帧格式、MocapFrame 定义
│ ├── codec/ 编解码器 Decoder.h / Encoder.h
│ ├── adapter/ UDP / BLE / WebSocket / LocalSocket / Binary 适配器
│ ├── types/ 关节枚举、Pose 类型
│ ├── pose_vizer/ 骨骼位姿 WebSocket 接口
│ └── tui/ 终端界面工具
├── lib/
│ ├── linux/x86_64/ SDK 动态库 + Qt 运行时 + CMake package
│ ├── linux/aarch64/ 同上(ARM64)
│ └── windows/x86_64/ 静态导入库 *.lib + CMake package
├── bin/ 现成程序(已配好运行库路径,可直接运行)
└── demo/
├── README.md 示例说明
├── docs/ 数据格式与接入文档
└── examples/ 示例程序| 文件 | 你怎么用 |
|---|---|
bin/forsense_mocap_viewer | 桌面窗口列出 64 个关节位姿。Windows 版缺 Qt 平台插件,目前启动不了。 |
bin/forsense_bin_recorder | 把收到的 UDP 帧录成 .bin 文件。 |
bin/forsense_bin_player | 回放 .bin 录制文件。 |
bin/forsense_mocap_pose_vizer | 把 MocapFrame 转发给 PoseVizer 可视化服务。 |
demo/examples/recv_mocap_udp.cpp | 自包含 C++ 示例(只用协议头 + 原生 socket,不需要 Qt、不需要 SDK 库、不用 CMake)。 |
demo/examples/compile.sh | 编译上面这份示例,生成 recv_mocap_udp。 |
demo/examples/recv_mocap_udp | 已编译好的示例程序(Linux 包里有)。 |
demo/examples/visual / visual.exe | 本地可视化服务(渲染器):内置 HTTP 服务 + Three.js 页面 + FBX 模型。先跑它再看画面。 |
demo/examples/udp_receiver.py | 数据桥:收 UDP → 转坐标系 → 上报给 visual。它自己不画图,必须和 visual 配对使用。 |
demo/docs/DataFormat.md | 1860 字节怎么排、CRC 怎么算。 |
demo/docs/Integration.md | 怎么接进自己的 C++ 工程。 |
include/ + lib/ | 二次开发时只要这两块。 |
bin/*_adapter.dll(Windows) | SDK 运行库,跑 bin 里的程序需要,别删。 |
Python SDK
G2L_Mocap_SDK_Python_1.0.0/
├── README.md 包内说明书
├── dist/forsense_mocap-1.0.0-py3-none-any.whl 唯一的安装包(三平台通用)
└── demo/
├── recv_mocap_udp.py 交互式菜单示例
├── udp_receiver.py 驱动网页可视化
├── docs/DataFormat.md 数据格式
└── visual / visual_linux_x86_64 / visual_linux_arrch64 / visual.exe| 文件 | 你怎么用 |
|---|---|
dist/*.whl | 要跑 Python 版菜单就必须装它(forsense_mocap 库),不装会报 No module named 'forsense_mocap'。装法见第二步。 |
demo/recv_mocap_udp.py | 交互式菜单。注意:包内这份的「3) 诊断模式」会报错,请换成本文件夹提供的 recv_mocap_udp.py,见第二步。 |
demo/udp_receiver.py | 配合 visual 在网页里看模型。 |
demo/visual* | 本地可视化服务,双击/直接运行,浏览器开 http://127.0.0.1:8765/。 |
各包 demo 的差异
- Windows 包的
demo/examples/里没有 C++ 源码和compile.sh,只有 Python 脚本和visual.exe;要在 Windows 上编 C++ 就用include/+lib/windows/x86_64/*.lib(见 接入 C++)。 - 两个 Linux 包(x86_64 / ARM64)反过来:只有 C++ 源码
recv_mocap_udp.cpp和预编译好的recv_mocap_udp,没有 Python 版recv_mocap_udp.py。 想要 Python 版就从本文件夹拷一份过去 —— 那份脚本纯 Python,全平台通用, 用法见第二步。
第一次用之前
MocapFrame 走网络,pico 动捕主机往你机器的 UDP 15000 端口发数据(默认端口)。 第一次跑之前确认这几件事:
| 情况 | 要做的 |
|---|---|
| Windows | 首次运行会弹防火墙提示,选允许(专用/公用网络都勾上);或手动放行 UDP 15000 入站,否则一个包都收不到。 |
| Linux | bin/ 里的程序已经配好运行库搜索路径,直接跑即可;自己编译的程序需要设 LD_LIBRARY_PATH(见下文)。 |
| 通用 | pico 主机和你的电脑要在能互通的网络里,且没有被防火墙拦 UDP。 |
要用 Python 版菜单(第二步的 recv_mocap_udp.py,或命令行 forsense-recv) | 必须先 pip install Python 包 dist/ 里的那个 wheel,否则一运行就报 ModuleNotFoundError: No module named 'forsense_mocap'。装法见第二步。 |
| 想用网页方案(第一步) | 不用装 Python 库:visual / visual.exe 是独立程序,udp_receiver.py 只用标准库。 |
第一步:先看画面(不写代码)
最短的验证路径:用 demo 自带的网页可视化,把 pico 主机发来的数据画成三维模型。 这条链路不依赖 Qt,Windows / Linux 都一样。
它有两个程序,缺一不可:
| 程序 | 作用 |
|---|---|
visual / visual.exe | 渲染器:内置 HTTP 服务 + Three.js 页面 + FBX 模型 |
udp_receiver.py | 数据桥:收 UDP → 转坐标系 → 把姿态 POST 给渲染器 |
udp_receiver.py 自己不画图,它只是把姿态推给渲染器(默认推往 http://127.0.0.1:8765/api/state)。单独跑它,8765 上没人监听,网页不会出来, 只会一直打印 State update failed。
1)先启动渲染服务(Windows 是 visual.exe)
cd demo/examples
./visual浏览器打开 http://127.0.0.1:8765/,不接数据时也可以手动拖着模型转。
2)再启动数据上报
python udp_receiver.py网页里的模型就会跟着实时数据动起来。
udp_receiver.py 可选参数:
| 参数 | 默认 | 含义 |
|---|---|---|
--host | 0.0.0.0 | UDP 绑定地址 |
--port | 15000 | UDP 监听端口 |
--url | http://127.0.0.1:8765/api/state | 状态上报接口(渲染器的地址) |
--mode | relative | 旋转空间;absolute 为对齐首帧的绝对旋转 |
--coord | mocap-to-three | 坐标转换;raw 为不转换 |
默认 relative 模式,输入已经是相对旋转,不需要标定。
注意:UDP 端口同一时间只能被一个进程绑定。跑着
udp_receiver.py时它占住了 15000,这时别的接收程序(终端菜单、桌面 viewer)会绑定失败 —— 要么先停掉它, 要么让它把数据转发出去。
第二步:在终端看数据(demo 菜单)
想在终端里一条条看数值就用示例程序,它提供了「全身 / 手部 / 诊断 / 退出」菜单:
===== Forsense Mocap CLI =====
1) 全身数据 # 打印全部 64 关节位姿
2) 手部数据 # 仅打印手部关节(15-34 左 + 44-63 右)
3) 诊断模式 # 连接状态 / 帧数 / 拒绝数 / length·id·crc 分类
4) 退出
===============================
请选择 [1-4]:- 数据界面内按 Ctrl+C 回到主菜单;在主菜单按 Ctrl+C 直接退出。
- 子界面里输入
m/0/q也能回主菜单。 - 诊断模式每 0.5 秒刷新一次,超过 2 秒没数据就判定「数据中断(可能断开)」。
Linux:先编译再跑
cd demo/examples
./compile.sh # 生成 recv_mocap_udp
./recv_mocap_udp # 默认端口 15000
./recv_mocap_udp --port 15001 # 换个端口这份示例不依赖 Qt、不依赖 SDK 库、也不用 CMake,只引用 SDK 协议头和原生 socket,所以很适合照抄。手动编译命令:
# Linux / macOS
g++ recv_mocap_udp.cpp -std=c++17 -I <sdk>/include -o recv_mocap_udp:: Windows(MSVC,需「x64 Native Tools 命令提示符」)
cl /std:c++17 /EHsc /I <sdk>\include recv_mocap_udp.cpp ws2_32.lib
:: Windows(MinGW)
g++ recv_mocap_udp.cpp -std=c++17 -I <sdk>/include -lws2_32 -o recv_mocap_udp任意平台:用 Python 版(Windows / Linux x86_64 / ARM64 通用)
recv_mocap_udp.py 是纯 Python 脚本,所有版本通用 —— 不挑系统也不挑架构, Windows、Linux x86_64、Linux ARM64 都能直接跑。
⚠️ 必须先把库装上,否则一定跑不起来。
这个脚本
import forsense_mocap,所以要先装 Python 包里那个 wheel。 没装就运行,会直接报:textModuleNotFoundError: No module named 'forsense_mocap'装法:进入 Python 包解压后的
dist目录,执行bashpip install forsense_mocap-1.0.0-py3-none-any.whl注意 Windows 右键「解压全部」常常会在外面再套一层同名目录,所以实际路径 可能是
G2L_Mocap_SDK_Python_1.0.0\G2L_Mocap_SDK_Python_1.0.0\dist\, 以能看到dist的那一层为准。装好可以自检一下:
bashpython -c "import forsense_mocap; print(forsense_mocap.__version__)"打印出
1.0.1是正常的:wheel 文件名写的是1.0.0,内部版本号是1.0.1, 装出来的就是 1.0.1,不是装错了。补充:第一步网页方案里的
udp_receiver.py只用 Python 标准库,不需要装这个 wheel;只有本节的recv_mocap_udp.py和命令行工具forsense-recv需要它。请用本文件夹里的
recv_mocap_udp.py,不要用包内那份。包内那份的「3) 诊断模式」调用了
recv.diagnostics(),而forsense_mocap库里并没有这个方法,一按 3 就报AttributeError。本文件夹这份改用recv.stats取统计,并额外打印实时 FPS,四条菜单都已实测正常。怎么换:覆盖包里同名的脚本即可 —— Windows 包在
demo\examples\recv_mocap_udp.py,Python 包在demo\recv_mocap_udp.py。 两个 Linux 包里没有这个 Python 脚本(它们给的是 C++ 版recv_mocap_udp.cpp),把本文件夹这份拷过去就能用。也可以放在任意目录直接运行, 不依赖 SDK 的目录结构。
菜单项和 C++ 版一致(1 全身 / 2 手部 / 3 诊断 / 4 退出),两处小差别:诊断模式 每秒刷新一次;拒绝原因按短包 / 帧头 / 帧 ID / CRC 分类。
Windows
python recv_mocap_udp.py # 默认端口 15000
python recv_mocap_udp.py --port 15001Linux x86_64 / ARM64
python3 recv_mocap_udp.py # 默认端口 15000
python3 recv_mocap_udp.py --port 15001端口被占用时程序会给出中文提示,关掉占用程序或换个端口即可。
录制与回放
bin/ 里带了两个工具,用于把现场的 UDP 流存下来,事后反复分析:
| 程序 | 作用 |
|---|---|
forsense_bin_recorder | 录制 UDP MocapFrame 到 .bin 文件 |
forsense_bin_player | 回放 .bin 文件 |
录制文件是连续的原始协议帧流,没有额外的容器头,因此体积小、也方便自己写 解析器。回放只认数据帧头 0xAA 0x55,并按帧内时间戳还原节拍。
接到自己的程序
确认上面「先看画面 / 终端看数据」都通了,再来改自己的工程。
接入 C++
你要带上的东西
include/forsense/(头文件目录)lib/<平台>/下的 SDK 库- Windows 还要带上
bin/里的*_adapter.dll、forsense_tui.dll以及 Qt6 的 DLL
前置条件:需要 Qt 6(Core、Network) 开发环境。
CMake 方式(推荐)
find_package(forsense_sdk CONFIG REQUIRED)
target_link_libraries(my_app PRIVATE forsense::udp_adapter)可用的 CMake 目标:forsense::udp_adapter、forsense::ble_adapter、 forsense::websocket_adapter、forsense::local_socket_adapter、 forsense::binary_adapter、forsense::pose_vizer、forsense::tui、 forsense::math(另有 fmt / magic_enum / eigen 依赖目标)。 CMake 找不到时指定 -Dforsense_sdk_DIR=<sdk>/lib/<平台>/<架构>/cmake/forsense_sdk。
最小接收代码
#include <forsense/adapter/UdpAdapter.h>
#include <forsense/codec/Decoder.h>
#include <forsense/protocol/human/MocapFrame.h>
fss::UdpAdapter udp;
udp.initialize();
udp.connect(QHostAddress::AnyIPv4, 15000); // 绑定 UDP 15000
fss::codec::DataDecoderT<fss::protocol::MocapFrame,
fss::protocol::MOCAP_DATA_FRAME_ID> decoder;
QObject::connect(&udp, &fss::UdpAdapter::data_received,
[&](const QByteArray &data, const QHostAddress &, quint16) {
for (char b : data)
{
if (decoder.parse(static_cast<std::uint8_t>(b)) !=
fss::codec::DataDecoderT<fss::protocol::MocapFrame,
fss::protocol::MOCAP_DATA_FRAME_ID>::Result::FRAME_READY)
continue;
const auto &frame = decoder.frame(); // 已通过 CRC 校验
// frame.payload.time_us : 时间戳(微秒)
// frame.payload.joint_poses[i] : 第 i 个关节
// .position[0..2] : (x, y, z)
// .quaternion[0..3] : (w, x, y, z)
}
});同样注意:UDP 端口同一时间只能被一个进程绑定。若已经有别的程序在收 15000(
udp_receiver.py、终端菜单或 viewer),你的程序要换端口,或者让它转发。
不用 Qt 的更简做法:直接抄 demo/examples/recv_mocap_udp.cpp。它只用 forsense/codec/Decoder.h + forsense/protocol/human/MocapFrame.h 两三个协议头,配原生 socket,一个文件搞定,编译见上一节的命令。
主要头文件对照:
| 想知道什么 | 看哪个头 |
|---|---|
| 帧结构 / payload 布局 | include/forsense/protocol/human/MocapFrame.h |
| 帧头常量、CRC 算法 | include/forsense/protocol/FrameFormat.h |
| 64 关节枚举 | include/forsense/types/SkeletonJoint.h |
| 位姿结构 | include/forsense/types/Pose.h |
| 流式解码器 | include/forsense/codec/Decoder.h |
| 编码器(构造/回放帧) | include/forsense/codec/Encoder.h |
| UDP 收发 | include/forsense/adapter/UdpAdapter.h |
接入 Python
先装库(wheel 在 Python 包的 dist/ 里,装法见解压一节):
pip install forsense_mocap-1.0.0-py3-none-any.whl最小用法:
from forsense_mocap import UdpMocapReceiver, JOINT_NAMES
def on_frame(frame):
head = frame.joint("Head")
print("Head:", head.position, head.quaternion)
UdpMocapReceiver(port=15000, on_frame=on_frame).start()轮询用法:
from forsense_mocap import UdpMocapReceiver
recv = UdpMocapReceiver(port=15000)
recv.start()
while True:
frame = recv.poll(timeout=1.0)
if frame is None:
continue
print(frame.timestamp_us, frame.joints[0].position)
# recv.stats.frames / recv.stats.rejected / recv.stats.rejected_causesPython API 一览:
| 名称 | 说明 |
|---|---|
JOINT_NAMES / JOINT_INDEX | 64 个关节名 / 名称 → 索引(与 C++ SkeletonJoint 顺序一致) |
MocapFrame | 一帧数据:timestamp_us、source、joints[64]、joint(name) |
MocapJoint | position(x,y,z) + quaternion(w,x,y,z) |
parse_frame(data) | 解析一帧字节(含 CRC 校验),失败返回 None |
make_frame(joints) | 构造一帧字节(测试 / 回放用) |
crc32_forsense(data) | Forsense CRC-32 |
UdpMocapReceiver(port, on_frame, on_error, on_status, timeout) | UDP 接收器,支持回调或 poll() 两种模式 |
RecvResult | 统计:frames、bytes、rejected、rejected_causes |
接收器还自带断开检测:超过 timeout(默认 2 秒)没收到数据, on_status 会回调 {"connected": False, "elapsed": ...},数据恢复后再回调 {"connected": True, "recovered": True}。端口被占用时 start() 抛 RuntimeError,带中文说明。
命令行工具(装完就有):
forsense-recv --port 15000
forsense-recv --port 15000 --joints Head Waist LeftHand RightHand读到的数据
帧结构
MocapFrame 固定 1860 字节,帧头 AA 55,ID 为 0。所有多字节整数和 float 都是小端。
AA 55 + id(u16 LE) + length(u16 LE) + payload(1850) + crc32(u32 LE)| 字段 | 长度 | 说明 |
|---|---|---|
| header1 / header2 | 1 + 1 | 0xAA / 0x55 同步字节 |
| id | 2 | 0(Mocap 数据帧) |
| length | 2 | 1850(payload 长度) |
| payload | 1850 | 见下表 |
| crc32 | 4 | Forsense CRC-32 |
Payload 布局(1850 字节)
| 偏移 | 长度 | 类型 | 成员 | 说明 |
|---|---|---|---|---|
| 0 | 8 | uint64 | time_us | 系统时间戳(微秒) |
| 8 | 1792 | float[64][7] | joint_poses | 64 个关节位姿 |
| 1800 | 9 | uint8 + float[2] | left_controller | 左手柄 / 手套状态 |
| 1809 | 9 | uint8 + float[2] | right_controller | 右手柄 / 手套状态 |
| 1818 | 32 | uint64[4] | reserved | 保留字段 |
每个关节固定 28 字节:position[3](偏移 0,x,y,z)+ quaternion[4](偏移 12,顺序是 w, x, y, z)。
64 个关节索引
| 序号 | 关节 | 序号 | 关节 | 序号 | 关节 | 序号 | 关节 |
|---|---|---|---|---|---|---|---|
| 0 | Head | 16 | LeftThumbMid | 32 | LeftPinkyMid | 48 | RightIndexNear |
| 1 | Neck | 17 | LeftThumbFar | 33 | LeftPinkyFar | 49 | RightIndexMid |
| 2 | Chest | 18 | LeftThumbEnd | 34 | LeftPinkyEnd | 50 | RightIndexFar |
| 3 | Spine1 | 19 | LeftIndexNear | 35 | RightCollar | 51 | RightIndexEnd |
| 4 | Spine2 | 20 | LeftIndexMid | 36 | RightShoulder | 52 | RightMiddleNear |
| 5 | Waist | 21 | LeftIndexFar | 37 | RightElbow | 53 | RightMiddleMid |
| 6 | LeftCollar | 22 | LeftIndexEnd | 38 | RightWrist | 54 | RightMiddleFar |
| 7 | LeftShoulder | 23 | LeftMiddleNear | 39 | RightHand | 55 | RightMiddleEnd |
| 8 | LeftElbow | 24 | LeftMiddleMid | 40 | RightHip | 56 | RightRingNear |
| 9 | LeftWrist | 25 | LeftMiddleFar | 41 | RightKnee | 57 | RightRingMid |
| 10 | LeftHand | 26 | LeftMiddleEnd | 42 | RightAnkle | 58 | RightRingFar |
| 11 | LeftHip | 27 | LeftRingNear | 43 | RightFoot | 59 | RightRingEnd |
| 12 | LeftKnee | 28 | LeftRingMid | 44 | RightThumbNear | 60 | RightPinkyNear |
| 13 | LeftAnkle | 29 | LeftRingFar | 45 | RightThumbMid | 61 | RightPinkyMid |
| 14 | LeftFoot | 30 | LeftRingEnd | 46 | RightThumbFar | 62 | RightPinkyFar |
| 15 | LeftThumbNear | 31 | LeftPinkyNear | 47 | RightThumbEnd | 63 | RightPinkyEnd |
拆开看:
- 全身骨骼:
0-14、35-43(24 个) - 左手:
15-34(20 个手指关节,来自 G2-L 手套) - 右手:
44-63(20 个手指关节)
数组索引是固定的,不要按关节名重新排序。
位置单位、坐标系方向以及四元数的参考坐标系,由 pico 动捕主机这一侧约定, 协议本身不带单位信息 —— 接进自己的引擎前,先和主机侧的配置对齐。
控制器 / 手套状态
left_controller、right_controller 各 9 字节:1 字节 button_state
- 4 字节
joystick_x+ 4 字节joystick_y。
| Bit | 置位含义 | 左侧 | 右侧 |
|---|---|---|---|
| 0 | 输入设备模式 | 手套(0 表示手柄) | 手套(0 表示手柄) |
| 1 | 摇杆按键按下 | 摇杆按键 | 摇杆按键 |
| 2 | 主按键按下 | X | A |
| 3 | 次按键按下 | Y | B |
| 4 | Trigger 按下 | Trigger | Trigger |
| 5 | Grip 按下 | Grip | Grip |
| 6 / 7 | 保留 | 忽略 | 忽略 |
摇杆两轴范围都是 [-1, 1];左摇杆 X 轴上正下负,右摇杆 X 轴右正左负, 两侧 Y 轴都是上正下负。
CRC-32
自定义 CRC-32:初始值 1,多项式 0xEDB88320(反射形式),逐字节按位处理, 不做最终异或。覆盖范围是从 header1 到 payload 最后一个字节, 不含 crc32 自身。
Python 参考实现:
def crc32_forsense(data: bytes) -> int:
crc = 1
for b in data:
crc ^= b
for _ in range(8):
crc = (crc >> 1) ^ 0xEDB88320 if crc & 1 else crc >> 1
return crc & 0xFFFFFFFF常见问题
| 现象 | 处理 |
|---|---|
| Windows 上一个包都收不到 | 防火墙是否放行 UDP 15000 入站(首次运行时选「允许」) |
跑 recv_mocap_udp.py 或 forsense-recv 报 ModuleNotFoundError: No module named 'forsense_mocap' | 没装库。这不是脚本的问题,进 Python 包的 dist 目录执行 pip install forsense_mocap-1.0.0-py3-none-any.whl,详见解压一节 |
| 绑定端口失败 / 提示端口被占用 | 同一端口同时只能一个进程用;先停掉正在占用它的那个(udp_receiver.py、终端菜单或 viewer),或改用 --port 15001 |
| Linux 服务器上没有图形界面 | 用 xvfb-run ./bin/forsense_mocap_viewer |
自己编译的程序报找不到 libQt6*.so | 设 export LD_LIBRARY_PATH=<sdk>/lib/linux/<架构>:$LD_LIBRARY_PATH;或直接用 bin/ 里的现成程序 |
find_package(forsense_sdk) 失败 | 加 -Dforsense_sdk_DIR=<sdk>/lib/<平台>/<架构>/cmake/forsense_sdk |
| 数据反复「中断(可能断开)」 | pico 主机是否在发、网络是否互通、有没有被防火墙/交换机拦 UDP |
| 关节数值看着不对 | 先确认单位与坐标系是主机侧约定;再确认你是按 64 关节固定索引取的,别按名字重排 |
| 重新从飞书下载的 Windows 包解压后目录套了三层 | 一路进到最里层(能看到 bin/include/lib/demo)再操作;本文件夹里的 zip 已去掉多余层级 |
解压报 Could not find a part of the path ...\Eigen\...\Transform.h | 多层目录 + include/forsense/third_party/eigen3 使路径超长。解压到更短的路径(如 D:\sdk),或用本文件夹里已去嵌套的 zip |
demo/recv_mocap_udp.py 选「3) 诊断模式」报 AttributeError | 包内这份脚本自身的问题。用本文件夹提供的 recv_mocap_udp.py 覆盖掉它即可,见第二步 |
网页里没画面 / 一直打印 State update failed | 渲染服务没起来。必须先跑 visual(或 visual.exe)再跑 udp_receiver.py —— 脚本只负责推数据,不负责画;确认 --url 指向的 8765 确实有人在监听 |
| 想让两个程序同时收数据 | UDP 端口只能被一个进程绑定,让一个程序收下来再转发(例如 forsense_mocap_pose_vizer) |
