无滑动滚动与全向轮:Pink非完整约束移动机器人控制完全实践

发布时间:2026/8/23 10:12:44
无滑动滚动与全向轮:Pink非完整约束移动机器人控制完全实践 无滑动滚动与全向轮Pink非完整约束移动机器人控制完全实践【免费下载链接】pinkPython inverse kinematics using Pinocchio and QP solvers项目地址: https://gitcode.com/gh_mirrors/pink1/pinkPink是一个基于 Pinocchio 与 QP二次规划求解器的 Python 逆运动学库它不仅能控制机械臂和人形机器人还能通过无滑动滚动约束RollingTask与全向轮任务OmniwheelTask优雅地处理轮式移动机器人的非完整约束——让轮子在地面上滚而不滑或者像全向轮底盘一样自由横移。本文带你完整走一遍这套控制实践。 先搞懂为什么轮子不打滑是非完整约束想象一个双轮机器人轮子在地面上滚动时接触点在水平面上的速度必须为零——它不能向侧面刮擦地板也不能向前打滑。这类约束有两个特点❌不能积分成位置限制你无法写出一个轮子只能出现在哪些位置的方程✅只约束速度它约束的是机器人构型的速度方向而非构型本身。在控制学里这就是经典的非完整约束nonholonomic constraint。传统的位置误差→位置限制的思路在这里失效必须把它写进速度层的优化问题中。这正是 Pink 的强项Pink 求解的是微分逆运动学输出的是机器人速度并把约束嵌入一个统一的 QP 问题里。滚动约束只需要提供误差函数和雅可比两样东西就能作为硬约束参与求解而不是像普通任务那样只是软性目标。 RollingTask把滚而不滑变成一行配置Pink 把滚动约束封装成了 pink/tasks/rolling_task.py 中的RollingTask类。你需要告诉它三件事参数含义hub_frame轮子轮毂在机器人模型中的坐标系名如left_wheelfloor_frame定义接触平面的地面坐标系通常是universewheel_radius轮子半径即轮毂到轮缘最近点的距离米它到底在约束什么内部会自动构造一个轮缘坐标系Rim原点落在轮毂投影到地面的接触点姿态与地面一致。然后生成一个 3 维误差向量x、y 两个分量为零→ 接触点在地面平面内零速度即不打滑z 分量 轮毂高度 − 轮半径→ 同时保持轮子贴地轮毂距离地面恰好一个轮半径。雅可比则由 Pinocchio 的框架雅可比自动导出并在轮缘坐标系下表达。整个推导过程可以在 pink/tasks/rolling_task.py 的compute_error与compute_jacobian两个方法中阅读逻辑非常清晰。关键技巧约束而非目标在控制循环中RollingTask是以constraints参数传入求解器的而不是放进 tasks 列表。这意味着 QP 求解器会优先满足无滑动条件再在可行速度中寻找最优解——这正是处理非完整约束的正确姿势。 OmniwheelTask放开横向让底盘横着走普通轮子的轮缘是窄窄的向侧面移动必然刮擦所以 x、y 两个方向都要约束。而全向轮omniwheel又称麦轮/poly wheel的轮缘装有一圈斜置滚子接触点在侧面方向上不受限制。OmniwheelTask见 pink/tasks/omniwheel_task.py正是RollingTask的轻量子类只做了两处改动误差向量从3 维降为 2 维只保留前后不打滑与保持离地高度雅可比相应地只取 2 行。一行之差物理意义却完全不同全向轮底盘可以原地平移、斜向移动、原地旋转而普通轮式底盘不行。 两个任务的实现都很薄核心继承自统一的 pink/tasks/task.py 基类——Pink 所有运动学任务FrameTask、PostureTask、ComTask……都遵循误差 雅可比这一套接口学习一个任务就学会了全部。 完整实践Upkie 双轮机器人无滑动行走examples/upkie_rolling.py 演示了一个带两条腿的双轮机器人Upkie如何边跑边保持轮子不打滑。整体流程只有四步加载机器人通过robot_descriptions载入 Upkie 的 URDF 模型并赋予自由浮动基座free-flyer root joint定义任务与约束目标任务底盘位置跟踪FrameTask 左右轮位置跟踪硬约束左右轮各一个RollingTask轮半径 0.06 mcost 设为 10.0 以示重视控制循环以 200 Hz 的固定频率循环——更新目标 → 调用solve_ik得到速度 →integrate_inplace积分得到新构型可视化用 MeshCat 实时显示机器人和目标坐标系。示例里有一个很妙的细节左右轮的位置目标随时间做正弦交错摆动0.1*sin(t)与-0.1*sin(t)仿佛在行走。而 RollingTask 约束保证了无论腿怎么摆轮子接触点始终静止于地面——步态由腿产生滚动由约束保证。solve_ik会自动从机器人模型读取关节位置与速度极限与滚动约束一并汇入同一个 QP。若想让动作更柔和只需给任务设置gain 1.0进行低通滤波见 pink/tasks/task.py 中gain属性说明。 进阶场景三全向轮移动底盘examples/mobile_omni_wheeled_robot.py 搭配 examples/robots/omnidirectional_wheeled_robot.urdf 展示了一台三全向轮移动机器人底盘平面运动三个全向轮以 120° 均布在底盘周围每个轮子有 0.7 rad/s 的速度极限。控制思路与前例一致但更简洁只有一个FrameTask追踪底盘位姿目标在两个跳跃点之间切换将base_task.gain设为0.05用低增益天然限速避免 QP 求解过快导致动作生硬求解器推荐daqp控制频率 100 Hz。这个示例还顺便演示了 Pink 文档中提到的 **screw path螺旋路径**概念底盘在平移的同时旋转轮子速度场自动由三个轮子的滚动关系解出——你只管给目标轮速分解由逆运动学完成不需要手写运动学解算公式。⚡ 快速上手清单步骤要点1️⃣ 准备模型轮子在 URDF 中必须有独立的revolute关节和命名清晰的轮毂 frame2️⃣ 普通轮子用RollingTask(hub_frame, floor_frame, wheel_radius, cost)3 维约束3️⃣ 全向轮用OmniwheelTask同名参数2 维约束放出横向自由度4️⃣ 接入求解作为solve_ik(..., constraints[...])传入与FrameTask等目标任务配合5️⃣ 调参cost决定约束有多硬gain控制收敛速度lm_damping兜底不可行目标想深入任务级单元测试在 tests/test_rolling_task.py 与 tests/test_omniwheel_task.py官方文档入口见 doc/index.rst 与任务总览 doc/tasks.rst。 小结轮子无滑动是典型的非完整约束约束速度、不可积分成位置Pink 把它做成RollingTask3 维误差 自动雅可比直接作为 QP硬约束参与求解OmniwheelTask只需去掉一个维度就解锁了全向轮的横向自由配合FrameTasksolve_ik的固定频率控制循环几行代码就能让双轮机器人无滑动行走、让三全向轮底盘横着走。掌握这套任务 约束的思维方式后你会发现 Pink 中其余 10 余种任务COM、姿态、阻尼、可操控性等的使用方式如出一辙——移动机器人控制的复杂度就这样被收进了一行行简洁的 Python 配置里。【免费下载链接】pinkPython inverse kinematics using Pinocchio and QP solvers项目地址: https://gitcode.com/gh_mirrors/pink1/pink创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考