NOTE · Autonomous Systems
Crazyswarm 与动作捕捉接入:兼容性和安全排障
整理历史 Crazyswarm1 接入动作捕捉 SDK 时可公开复用的兼容性检查、数据链验证和禁飞条件。
本页记录接口边界、历史实验现象和排障方法。动作捕捉供应商 SDK 应从正式渠道获取,并遵守其许可;不要把 SDK 压缩包、私有头文件、动态库或任何密码、Token、私钥提交到公开仓库。普通设备编号、内网地址和配置坐标本身不作为秘密,但必须标明它们只是旧环境样本。
版本边界
原始 Crazyswarm 文档主要面向 Ubuntu 20.04、Python 3.7 与 ROS Noetic。该仓库已经声明不再积极维护,ROS Noetic 也已于 2025 年 5 月 31 日结束支持。因此:
- 历史结果复现:固定操作系统镜像、Crazyswarm commit、submodule commit、固件和 SDK 版本。
- 新项目:优先评估 ROS 2 与 Crazyswarm2。
- 不能假设兼容:同名 SDK 在不同 CPU 架构、glibc、编译器 ABI 或 ROS 环境中未必可以直接替换。
历史实验中可公开的现象
实验记录包含一批具体机号和现场结论。机号本身不是凭据,下面把它们作为历史实验样本;未经闭环诊断的判断不能写成普遍结论:
- 起飞翻倒先做机械检查:当时实验中,多次起飞异常最终发现桨叶已有不易察觉的裂纹;更换完好桨叶后现象消失。每次飞行前应逐片轻压检查裂纹、缺口和安装方向,而不是先调控制器。
- 故障始终跟随同一机体时先隔离硬件:交叉更换桨叶、电机、固件、位置和无线配置,记录故障是跟随机体、位置还是软件通道。没有完成矩阵式交叉测试前,不能把个案归因于某一代软件。
- 低级机群命令应覆盖所有活动机体:当时实验观察到,只向部分机体持续发送低级位置命令可能引出非预期行为。结论只能写成检查项:确认所用 Crazyswarm commit 的 setpoint 语义、广播或逐机循环和 watchdog 要求,并在无桨状态核对每个活动 ID 都收到预期命令。
另一次实验记录了速度命令往返后的残余位置误差。闭环跟踪误差可能来自定位、坐标变换、时延、控制器和机体差异,不能仅凭这一现象判定某个控制接口“有问题”。
更完整的历史实验现象如下:
| 旧记录 | 现在应如何解释 |
|---|---|
| 4、7、18 号在起飞阶段反复异常;7、18 号起飞即翻倒,检查发现桨叶开裂,更换后恢复 | 对 7、18 号可以确认当次机械故障与裂桨相关;不能据此推断所有翻倒都由桨导致 |
| 4 号有时绕大圈、不稳,有时起飞坠落;更换桨、电机、刷新固件后仍出现 | 应暂时停用并做机架、电机/电调、传感器、供电、定位和配置的交叉试验;“4 号有问题”只是现场隔离决定,不是根因 |
cmdposition 只遍历部分活动机体时,未被持续更新的机体和其他机体出现非预期位置关系 | 必须核对该 commit 的低级命令刷新要求,并对所有活动 ID 做无桨 setpoint 审计 |
对方系统的 cmdposition 没观察到掉高;双方 cmdvelocity 往返都存在约半格位置误差 | 属于对照观察,缺少格长、轨迹、时间戳和控制参数,不能用于比较控制栈优劣 |
| “扩展坞 + PA”四机正常,而同一批机体在另一套“2.0”组合下混乱 | 原记录没有保存这两个标签的完整硬件/软件版本,只能作为待复现实验线索 |
下面两张机械检查照片未显示姓名或凭据:


先选择一条清晰的数据链
常见接入可以抽象为:
相机与供应商软件
↓
供应商流或 SDK
↓
动作捕捉适配层
↓
ROS 位姿消息
↓
Crazyswarm / 控制程序
每一层都应单独验证。不要同时启用多个程序争用同一数据流,也不要在适配层和控制程序中各做一遍未经记录的坐标变换。
SDK 的二进制兼容性
接入前先记录以下信息:
- SDK 精确版本和获取日期。
- 目标操作系统、CPU 架构、glibc 与编译器版本。
- 动态库依赖和运行时搜索路径。
- SDK 使用的坐标约定、长度单位、时间戳语义与网络传输方式。
下面的命令只做诊断,不修改系统:
uname -m
ldd --version | head -n 1
file /path/to/libVendorSdk.so
ldd /path/to/libVendorSdk.so
readelf -d /path/to/libVendorSdk.so
如果 ldd 显示 not found,先查清缺失库来自系统、ROS 工作空间还是供应商 SDK。不要用随意复制同名 .so 或创建错误软链接的方式掩盖 ABI 问题。
历史 Nokov 接入方式如何安全复现
原始 Crazyswarm1 配置文档记录的是特定 XING/Nokov 版本;后续实验又使用过另一版供应商包。两者的头文件、动态库名和 ABI 不能互换。安全复现应遵循:
- 从供应商正式渠道取得与许可相符的 SDK,不从本站下载二进制副本。
- 把原始压缩包校验值、版本号、CPU 架构和获取日期写入私有环境清单。
- 在项目内的依赖目录或专用前缀中解压,先编译 SDK 自带的最小接收示例。
- 用
file、ldd和readelf检查动态库,再让libmotioncapture链接该精确版本。 - 通过 CMake 配置选项启用 Nokov 支持;不要依赖“修改第 8 行/第 10 行”这类会随版本失效的说明。
- 优先用 RPATH、CMake 的明确库路径或受控启动环境寻找
.so,不要为了省事复制到/usr/lib。 - 在工作空间根目录构建,并保存完整编译输出;只有 SDK 最小示例和适配层单测都通过后才连接 Crazyswarm。
当时实验使用的供应商包要求在 NOKOVSDKClient.h 中启用 Linux 分支,并在该 checkout 的 libmotioncapture CMake 选项中打开 Nokov。下面两张图只记录当时文件位置;行号和宏名称可能随 SDK 改变,不能机械照抄:


实验记录中的包名是 XING_Linux_C++_SDK_4.1.0.5634.zip;原始 Crazyswarm 文档则写明测试过 XING 1.0.0.2456。版本号明显不相同,因此这里只把文件名作为环境线索,不提供压缩包下载,也不宣称两者 ABI 兼容。
历史目录结构通常类似:
crazyswarm/
└── ros_ws/src/crazyswarm/
└── externalDependencies/libmotioncapture/deps/
└── nokov_sdk/
├── include/
└── lib/
这是归档结构示意,不代表任意新版 SDK 都必须使用同样目录。重新构建前先查看当前 checkout 的 README 与 CMake 选项;在可丢弃的复现副本中清理旧构建产物,不把删除目录写成面向所有人的固定命令。
如果不直接走供应商 SDK,另一条历史链路是供应商/VRPN 流 → vrpn_client_ros → ROS 位姿话题。它增加了一层消息转换,但便于单独观察位姿;同样必须锁定 ROS 发行版和仓库 commit,并核对 frame、单位与时间戳。
分层验证流程
1. 供应商软件层
在连接 ROS 前确认:
- 预期数量的刚体持续可见。
- 静止刚体的位置噪声、姿态和跟踪质量正常。
- 遮挡和重新出现的行为可预测。
- 刚体名称唯一,且不包含设备序列号、人员或场地信息。
2. SDK / 网络层
确认适配程序能持续收到帧,并记录帧号、时间戳和刚体数量。网络不通时区分单播、广播或组播,检查对应接口、路由与防火墙;不要通过关闭整机防火墙来验证。
3. ROS 消息层(历史 ROS 1 环境)
使用占位话题名检查消息是否存在、频率是否稳定以及时间戳是否更新:
rostopic list
rostopic hz /mocap/rigid_body/pose
rostopic echo -n 1 /mocap/rigid_body/pose
重点核对:
header.stamp是否持续前进,而不是重复旧帧。frame_id是否明确且与控制系统约定一致。- 位置单位是否为米,四元数是否归一化。
- 丢帧后是否能被检测,是否存在不受限的旧值保持。
4. Crazyswarm 配置层
机体 ID、无线配置和动作捕捉刚体名之间应使用显式的一对一清单。不要依赖:
- 刚体在数组中的返回顺序。
- 启动时“最近的位置”。
- 运行中仅凭相邻帧距离重新分配身份。
任何身份歧义都应触发禁飞,而不是由控制器猜测映射。占位配置适合直接复制;随后也给出当时实验的普通内网地址,便于对应现场配置。
历史 ROS 1 启动文件中的核心配置可以用不可运行的占位符表达:
motion_capture_type: "nokov"
motion_capture_host_name: "MOCAP_HOST"
object_tracking_type: "motionCapture"
当时的实验环境记录为:
motion_capture_type: "nokov"
motion_capture_host_name: "10.1.1.198"
10.1.1.198 是当时局域网端点,不是凭据,也不保证在其他网络可达。迁移环境时应从当前网络配置重新确认主机地址。
- 每台机体具有唯一刚体时,
motionCapture让供应商软件负责身份识别;刚体命名必须与机体映射表一致。 - 使用重复 marker arrangement 或单 marker 时,历史 Crazyswarm 可通过
libobjecttracker处理原始点集,但会依赖初始位置并面临遮挡后的身份恢复问题。 - 使用
libobjecttracker时,供应商软件若先把 marker 从原始点流中“捕获/移除”,下游可能看不到所需数据。应在录制数据上先验证点流,而不是直接起飞试错。
MOCAP_HOST 适合通用模板;部署文件也可以写普通内网地址,但仍不得混入用户名密码、Token、私钥或供应商授权文件。
5. 无桨坐标检查
取下所有桨叶,手持一台机体分别沿场地 +x、+y、+z 移动并绕各轴缓慢旋转,确认:
- RViz、日志和供应商软件中的方向一致。
- 一米实际位移对应约一米数据变化。
- 静止时没有持续漂移或突然跳到其他刚体。
- 遮挡时系统进入明确的无效状态,而不是继续使用无限期旧位姿。
常见错误与定位层级
| 现象 | 最可能层级 | 下一步证据 |
|---|---|---|
| 编译时找不到头文件 | include 路径或 SDK 版本 | 查看 CMake 实际编译命令与 SDK 目录 |
wrong ELF class | 32/64 位或架构不一致 | file、uname -m |
undefined reference | 链接顺序、ABI 或缺少依赖 | 构建详细日志、nm / readelf |
运行时找不到 .so | 动态库搜索路径 | ldd、readelf -d |
| 已连接但没有帧 | SDK 端点、网络模式或防火墙 | SDK 自带最小示例和抓包计数 |
| ROS 有话题但位姿冻结 | 时间戳或适配层线程 | 连续比较帧号与 header.stamp |
| 两台机体身份互换 | 刚体命名或配置映射 | 停止飞行,逐个刚体核对清单 |
| 位姿方向或尺度错误 | 坐标变换或单位 | 无桨三轴手持测试 |
起飞门槛
只有以下条件全部成立,才从接口验证进入实机飞行:
- 每个活动机体都有唯一、显式且稳定的刚体映射。
- 坐标系、单位、姿态约定和时间戳已通过无桨测试。
- 位姿新鲜度、丢帧和遮挡能够触发停止条件。
- 无线链路、电池和固件版本均已逐机检查。
- 先完成单机短时低风险悬停,再逐步扩展数量。
- 现场具备安全区、桨叶保护和独立于主控制循环的停机手段。