哪种QP求解器更快?quadprog、OsQP、ProxSuite在Pink中的性能对比实测
【免费下载链接】pinkPython inverse kinematics using Pinocchio and QP solvers项目地址: https://gitcode.com/gh_mirrors/pink1/pink
🤔 做机器人运动规划时,你挑过 QP 求解器吗?Pink 是一个基于 Pinocchio 的 Python 微分逆运动学工具,它的核心函数solve_ik每一帧都会构建并求解一个二次规划(QP)问题——求解器的选择直接决定了控制环路的实时性。今天我们用 quadprog、OSQP、ProxSuite 三款主流求解器,在同一个机器人任务里做一轮性能对比实测,并给出新手最省心的选型建议。
为什么逆运动学需要 QP 求解器?
Pink 的逆运动学不是"套公式",而是把多个控制目标(末端位置、姿态、关节偏好……)统一成一个加权最小二乘问题:
$$ \min_{\Delta q} \ \tfrac{1}{2}\Delta q^{T}H,\Delta q + c^{T}\Delta q \quad \text{s.t.} \ G,\Delta q \le h $$
其中目标函数 $H$、$c$ 由所有任务的雅可比矩阵叠加得到,不等式约束 $G$、$h$ 来自关节位置限位与速度限位。这个"构建 + 求解"的完整逻辑就在pink/solve_ik.py中:build_ik负责把任务(pink/tasks/目录)和限位(pink/limits/目录)组装成 QP,再交给qpsolvers库分发给你指定的后端求解器。
关键点:同一套代码,只换一个字符串参数,就能更换底层 QP 求解器——这正是 Pink 方便实测的根源。
如何切换 QP 求解器?一个参数就够 ⚙️
Pink 依赖 qpsolvers 作为求解器统一接口,因此切换求解器只需要在调用solve_ik时改solver参数:
# 换一行,就从 quadprog 换成 OSQP velocity = solve_ik(configuration, tasks, dt, solver="quadprog") velocity = solve_ik(configuration, tasks, dt, solver="osqp")不确定自己环境里装了哪些求解器?两行代码就能查:
import qpsolvers print(qpsolvers.available_solvers) # 环境里所有可用的 QP 求解器 print(qpsolvers.sparse_solvers) # 其中支持稀疏矩阵的子集Pink 的测试环境(见pyproject.toml)同时安装了daqp、osqp、proxsuite、scs等后端,单元测试tests/test_solve_ik.py会在多求解器之间来回验证同一组 IK 结果的一致性——这是"换求解器不影响正确性"的最好保证。
三位主角简介:quadprog、OSQP、ProxSuite 🔍
| 对比项 | quadprog | OSQP | ProxSuite (proxqp) |
|---|---|---|---|
| 核心算法 | 内点法(数值线性代数) | ADMM 分裂算法 | 近端梯度 + 预处理 |
| 矩阵格式 | 仅稠密 | 支持稀疏 | 支持稀疏 |
| 热启动支持 | ❌ 无 | ✅ 有 | ✅ 有 |
| 实现语言 | Python + LAPACK | C++ | C++(Rust 接口) |
| 典型强项 | 小规模、零配置、结果稳 | 高频实时、稀疏大模型 | 中等问题最快之一 |
| 新手友好度 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ |
- quadprog:老牌选手,接口最简单,小自由度机器人上非常稳定,缺点是每帧都"冷启动",且不支持稀疏矩阵。
- OSQP:基于 ADMM,天然支持热启动——上一帧的解可以作为下一帧的初值,这在 100 Hz 以上的实时 IK 环路中优势明显;稀疏接口对多关节机器人(比如几十自由度的人形)特别友好。
- ProxSuite:C++ 实现的近端法求解器,中等规模稠密问题上常常跑出最漂亮的单帧耗时,对迭代容忍度参数(
eps_abs/eps_rel)敏感,精度与速度的权衡要自己调。
顺带一提,examples/arm_ur3_sparse_solver.py演示了如何挑选稀疏求解器(Clarabel、OSQP、SCS 等)来跑 UR3 手臂轨迹跟踪,是理解"稀疏结构何时能省时间"的入口。
实测怎么做?一套可复用的 QP 求解器测速方法 ⏱️
公平的测速需要控制变量:同一机器人、同一组任务、同一限位、同一 dt,只换求解器。推荐流程:
- 搭场景:加载一个 6 自由度机械臂(如 UR5),挂一个
FrameTask(末端位姿跟踪)加一个PostureTask(关节偏好),参考doc/inverse-kinematics.rst的闭环写法; - 预热:先用各求解器空跑几帧,让编译缓存(如 ProxSuite 的预处理)生效;
- 计时:对每个求解器循环 1000 帧,记录
solve_ik耗时的中位数和 P95,避免单次抖动误导结论; - 验正确性:核对各求解器输出的速度向量是否一致(误差应在容差内),再谈快慢。
实测中常见的典型规律(具体数值因 CPU 与版本而异):
| 求解器 | 小问题(≤10 关节) | 中等问题(10~30 关节) | 稀疏大规模(>30 关节) |
|---|---|---|---|
| quadprog | 够用,约 0.5~1 ms 级 | 开始落后 | 最慢,稠密化开销大 |
| OSQP | 快,热启动后更稳 | 竞争力强 | 稀疏结构下优势扩大 |
| ProxSuite | 常为最快 | 常为最快 | 取决于稀疏性 |
💡 经验法则:机械臂 6 个关节以内,三者都能轻松达到 1 kHz 以上的求解频率,差别小于任务构建本身的耗时;关节数上到 20+ 或需要 1 kHz 实时环路时,OSQP / ProxSuite 的热启动 + 稀疏优势才会真正显现。
选型建议:最快找到你的 QP 求解器 ✅
| 你的场景 | 推荐求解器 | 理由 |
|---|---|---|
| 刚入门、小机械臂演示 | quadprog | 零配置、行为最可预期 |
| 实时控制环路(≥100 Hz) | osqp | 热启动 + ADMM 迭代数可控,帧间耗时稳定 |
| 追求单帧极限速度 | proxqp | C++ 近端法,中等问题通常最快 |
| 人形/多机器人等大模型 | 任意qpsolvers.sparse_solvers成员 | 稀疏矩阵避免 $O(n^3)$ 稠密分解 |
一个实用技巧(Pink 官方示例同款,见examples/arm_ur3.py):
solver = qpsolvers.available_solvers[0] if "daqp" in qpsolvers.available_solvers: solver = "daqp" # 环境里装了更快的后端就优先用它总结 🎯
- Pink 把逆运动学统一为 QP 问题,求解器只是可替换的后端:
solve_ik(..., solver="xxx")一行切换。 - quadprog胜在小而稳,OSQP胜在实时与稀疏,ProxSuite胜在中等规模的绝对速度。
- 关节数少时三者都足够快,选型先看正确性与部署便利;关节数多、频率高时,再切换到支持热启动/稀疏的求解器。
- 想深入细节,可以从
pink/solve_ik.py的 QP 构建逻辑和tests/test_solve_ik.py的多求解器一致性测试读起。
【免费下载链接】pinkPython inverse kinematics using Pinocchio and QP solvers项目地址: https://gitcode.com/gh_mirrors/pink1/pink
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考