Pink的13种任务全家福:FrameTask、PostureTask与ComTask如何选怎么用
【免费下载链接】pinkPython inverse kinematics using Pinocchio and QP solvers项目地址: https://gitcode.com/gh_mirrors/pink1/pink
Pink 是一个基于 Pinocchio 和 QP 求解器的Python 逆运动学库,它的核心思想是把机器人控制拆成一组"任务"(Task):每个任务定义一个要驱动到零的误差,加权合并成一个二次规划问题统一求解。Pink 一共提供13 种任务类,涵盖末端定位、姿态正则、质心控制、关节耦合、全向轮约束等场景。本文带你 30 秒看懂 13 种任务,并掌握 FrameTask、PostureTask、ComTask 三大主角的选择方法与调参技巧。
一、30 秒理解:Pink 任务如何工作?
在 Pink 中,每个任务定义一个误差函数 e(q),目标是把它驱动到零。多个任务同时存在时,Pink 通过cost(代价权重)把不同单位(米、弧度)的误差归一化到统一量纲,再交给 QP 求解器求出一组速度:
| 概念 | 含义 | 新手要点 |
|---|---|---|
| 误差 e(q) | 当前状态与目标的差距 | 驱动到零即完成 |
| cost | 归一化权重 | 数值越大优先级越高 |
| target | 任务目标值 | 通过set_target()设置 |
| solve_ik | 求解入口 | 自动处理位置/速度限位 |
一句话总结:任务管"做什么",cost 管"多重要",solve_ik 管"怎么动"。
二、13 种任务全家福一览表 📋
Pink 的 13 种任务都在 pink/tasks/ 目录下实现,全部从抽象基类 pink/tasks/task.py 派生:
| # | 任务类 | 一句话功能 | 典型场景 | 源文件 |
|---|---|---|---|---|
| 1 | Task | 抽象基类,定义误差/雅可比接口 | 自定义任务的起点 | pink/tasks/task.py |
| 2 | FrameTask | 让某坐标系的位姿(位置+朝向)跟踪世界系目标 | 末端执行器定位,最常用 | pink/tasks/frame_task.py |
| 3 | RelativeFrameTask | 让某坐标系相对另一个坐标系保持目标位姿 | 手持相机、双手机器人协作 | pink/tasks/relative_frame_task.py |
| 4 | ComTask | 让机器人质心跟踪目标位置 | 人形机器人平衡控制 | pink/tasks/com_task.py |
| 5 | PostureTask | 把关节角拉向偏好姿态(不碰浮动基座) | 姿态正则化,防奇异 | pink/tasks/posture_task.py |
| 6 | JointVelocityTask | 跟踪给定的关节速度参考值 | 速度级伺服控制 | pink/tasks/joint_velocity_task.py |
| 7 | DampingTask | 最小化关节速度(JointVelocityTask 的特例,目标为零) | 减少多余运动 | pink/tasks/damping_task.py |
| 8 | LowAccelerationTask | 最小化当前速度与上一拍速度的差 | 让动作更平滑 | pink/tasks/low_acceleration_task.py |
| 9 | ManipulabilityTask | 最大化操作度指标 | 远离奇异位形 | pink/tasks/manipulability_task.py |
| 10 | LinearHolonomicTask | 施加线性完整约束 ∑aⱼ·qⱼ = b | 自定义关节间线性关系 | pink/tasks/linear_holonomic_task.py |
| 11 | JointCouplingTask | 按固定比例耦合两个旋转关节(如 q₁−q₂=0) | 双驱动同步关节 | pink/tasks/joint_coupling_task.py |
| 12 | RollingTask | 轮子无滑滚动约束 | 轮式机器人、Upkie 滚动 | pink/tasks/rolling_task.py |
| 13 | OmniwheelTask | 麦轮/全向轮的非完整约束 | 全向移动底盘 | pink/tasks/omniwheel_task.py |
💡 记忆口诀:定位看 Frame、姿态看 Posture、平衡看 Com、平滑看 LowAcceleration、避奇异看 Manipulability、轮子看 Rolling/Omniwheel。
三、三大主角怎么选怎么用?
3.1 FrameTask:末端定位的"瑞士军刀" 🦾
FrameTask 是绝大多数场景的第一选择——只要你需要"让某个连杆到达某个位姿",就用它。它可以分别设置位置代价和朝向代价,且都支持各向异性(不同轴不同权重):
tasks["base"] = FrameTask( "base", position_cost=1.0, # [cost]/[m],标量 = 各向同性 orientation_cost=1.0, # [cost]/[rad] )怎么选:
- 只关心位置不关心朝向(如脚底接触面)→
orientation_cost=0.0,位置代价可用向量[0.1, 0.0, 0.1]只约束前后左右 - 目标要挂在"另一个移动坐标系"下(而非世界系)→ 换用
RelativeFrameTask
目标可用set_target(transform)直接给齐次变换矩阵,或用set_target_from_configuration()把当前位姿"冻结"为目标(详见 pink/tasks/frame_task.py)。
3.2 PostureTask:几乎必加的"压舱石" ⚖️
PostureTask 把各关节角拉向一个偏好姿态(常用机器人中立位),典型代价设得很小(1e-3 量级),起正则化作用:
- 主任务接近奇异时(如腿部伸直、雅可比降秩),它会自动把膝关节拉回偏好角度,避免"软脚"
- 浮动基座坐标不受它影响,不会干扰位姿任务
怎么选:主任务 + PostureTask 是 Pink 最经典的"黄金组合"。几乎每个全身控制示例(双足、四足)都带着它,代价一般取主任务的 1/100 左右。
3.3 ComTask:平衡控制的核心 🧍
ComTask 把机器人质心拉向目标点,3 维位置误差、3 维代价:
com_task = ComTask(cost=1.0) com_task.set_target(target_com) # 世界系下的目标质心位置怎么选:
- 人形/四足做原地平衡、CoM 轨迹跟踪 → ComTask
- 只需"姿态别乱晃"而不需要精确质心轨迹 → 通常不必加,PostureTask 就够了
质心目标也可用set_target_from_configuration()从某个构型自动计算。
四、5 秒决策:我该用哪个任务?
按你的控制目标对号入座:
- "末端/连杆去某个世界系位姿"→
FrameTask - "A 连杆相对 B 连杆保持位姿"→
RelativeFrameTask - "质心到某个点"→
ComTask - "关节别偏离偏好姿态太遠"→
PostureTask(低代价) - "动作太抖、希望更柔和"→ 加
LowAccelerationTask,或给任务调小gain - "卡在奇异位形附近"→ 加
ManipulabilityTask - "两个关节要联动/同步"→
JointCouplingTask - "轮子不能打滑 / 全向轮"→
RollingTask/OmniwheelTask - "关节速度要跟踪参考值"→
JointVelocityTask;只想"能慢就慢" →DampingTask
五、cost 调参:任务之间如何"分蛋糕"?
所有任务的误差单位不同(米 vs 弧度),Pink 用 cost 把它们换算成统一的"归一化代价"。代价是相对概念:
- 任务 A 位置代价 1.0,任务 B 代价 0.1 → 同样 1cm 误差,A 的"痛感"是 B 的 10 倍,求解器会优先满足 A
- 位置代价单位 [cost]/[m],朝向代价单位 [cost]/[rad],标量即各向同性,向量按帧坐标轴分量分别加权
调参经验值(人形双足示例):
| 任务 | 位置代价 | 朝向代价 |
|---|---|---|
| 基座 base(主任务) | 1.0 | 1.0 |
| 左/右接触点(次任务) | [0.1, 0.0, 0.1] | 0.0 |
| PostureTask(正则) | — | 1e-3 |
另外两个通用旋钮:gain(0~1,越小响应越平滑,类似低通滤波)和lm_damping(目标不可达时的 Levenberg-Marquardt 阻尼,抖动大时适当调高)。
六、上手三步走:从定义到求解
完整工作流只有三步(详见 README.md 与 doc/tasks.rst):
dt = 6e-3 for t in np.arange(0.0, 42.0, dt): velocity = solve_ik(configuration, tasks.values(), dt) # ① 求解速度 configuration.integrate_inplace(velocity, dt) # ② 积分到构型 time.sleep(dt) # ③ 下一拍- 每个任务先设 cost、再
set_target(...)设定目标,才能加入求解 solve_ik会自动读取机器人模型中的位置限位与速度限位,无需手写约束- 目标持续更新 → 机器人持续跟踪;目标静止 → 收敛到稳态构型
七、新手常见疑问 FAQ
Q1:Pink 能解全局逆运动学吗?Pink 是微分(局部)方法,收敛到代价函数的最近极值点;若目标不可达可能卡在某处,可加ManipulabilityTask或调低gain缓解。
Q2:任务数量有上限吗?没有硬性上限,但任务越多 QP 越大、越容易互相冲突——用 cost 明确优先级即可。
Q3:想实现自己的任务怎么办?继承 pink/tasks/task.py 中的Task,实现compute_error()和compute_jacobian()两个抽象方法,QP 目标会自动构建。参考 tests/ 目录下的各任务单测写法。
Q4:更多实际案例在哪看?examples/ 目录收录了 UR5/Panda 机械臂、双足 Upkie 滚动、四足 Go2 蹲姿、人形 Draco3 等丰富示例;碰撞避免类任务可结合 pink/barriers/ 中的屏障使用。
结语
Pink 的 13 种任务各司其职:FrameTask 管定位、PostureTask 管姿态、ComTask 管平衡,其余任务按需拼装。记住"任务定义目标、cost 分配优先级、solve_ik 统一求解"这条主线,你就能从容应对从机械臂到双足人形的各种逆运动学挑战了。
【免费下载链接】pinkPython inverse kinematics using Pinocchio and QP solvers项目地址: https://gitcode.com/gh_mirrors/pink1/pink
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考