ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Pinocchio机器人动力学库安装全攻略:从环境配置到源码编译

Pinocchio机器人动力学库安装全攻略:从环境配置到源码编译 很多人学完《机器人学导论》推了一整本 DH 参数手算正逆运动学结果一进项目实战就卡住了——不是公式不会而是要用代码把几十个关节的动力学算出来自己从零写根本遭不住。这时候 Pinocchio 就派上用场了。这篇文章不是泛泛介绍而是我实际摸过几遍之后的安装全记录从环境选型到源码编译再到常见坑尽量让你照着走一遍就能稳定用起来。1. 在动手安装前先确认 Pinocchio 值不值得装1.1 一个库覆盖了机器人学教科书大半的公式Pinocchio 是 INRIA 开源的刚体动力学计算库名字取自《木偶奇遇记》里的小木偶匹诺曹——机器人全身关节也是如此牵一发动全身。它把教科书里的正运动学、逆运动学、雅可比、动力学质量矩阵、RNEA 逆动力学、重力补偿这些算法全部封装成 C 接口和 Python 绑定只要你提供一个 URDF 模型描述就能直接算出你想要的量。我当时第一次用的时候感受是起了个大早赶了个晚集自己手推的逆动力学代码里全是索引错误调试到凌晨三点都没调明白换成 Pinocchio 之后一个pin.rnea(model, data, q, v, a)直接出关节力矩速度还比我自己实现的暴力循环快一个数量级。原因在于它内部用了空间代数spatial algebra的表达力和速度都在李代数层面做运算推导逻辑和最新论文对得上。1.2 和 RBDL、Drake 这些竞品比它强在哪做足式机器人、机械臂控制的人选动力学库的时候绕不开三个名字RBDL、Drake、Pinocchio。RBDL 相对轻量但更新频率一般URDF 之外的模型支持有限Drake 功能全但体积大、构建重适合整个仿真管线都在它生态里跑的团队Pinocchio 正好卡在中间——轻量、性能极好、还有活跃社区。还有一个很多人不太注意的点Pinocchio 和 HPP、Gepetto-viewer、TALOS 这些动作规划生态是捆在一起的如果你后面要做步态规划、MPC 控制它会比 RBDL 顺很多。在实际工程里我见过好几个机器人团队的动力学模块都是pinocchio crocoddyl这个组合。所以它叫机器人学的必备库并不夸张。2. 环境选型Ubuntu、Windows、macOS 各自的依赖准备2.1 虚拟机与双系统Ubuntu 版本怎么选如果你是 Windows 用户我强烈建议别在 Windows 上直接硬刚编译。Pinocchio 在 Windows 上确实有 conda 包但遇到问题搜索解决方案时的资料基本都是 Linux 向的光是对着报错翻译系统差异就能消耗你半天。最好的做法是装一个 VMware 虚拟机或者 WSL2跑 Ubuntu 20.04 或 22.04。Ubuntu 版本上20.04 和 22.04 我都试过都对 Pinocchio 很友好。区别在于 22.04 自带 GCC 11、CMake 3.22源码编译时基本不用升级工具链20.04 自带的 GCC 9 也够用。如果你后面还要装 ROS那就看你要用 ROS 哪个版本——Noetic 配 20.04Humble 配 22.04。虚拟机配置方面编译源码时建议至少给 4 核和 8G 内存不然make起来风扇转得让人心疼。macOS 用户直接用 conda 是最省事的源码编译需要 Xcode Command Line Tools而且 OpenMP 和 Boost 的版本在 Apple Silicon 上有时候会闹脾气我后面会细说。总而言之环境选型的优先级是Linux 原生 WSL2/虚拟机 macOS conda Windows 原生。2.2 依赖梳理性别搞混Boost、Eigen、URDF 解析器缺一不可源码编译之前先把依赖装齐。Pinocchio 的核心底层依赖是 Eigen3线性代数、Boost系统与文件组件、urdfdomURDF 文件解析、assimp网格模型加载。这些缺一个编译到一半就给你脸色看。Ubuntu 下执行这一串sudo apt update sudo apt install -y build-essential cmake \ libboost-system-dev libboost-filesystem-dev libboost-test-dev \ libeigen3-dev liburdfdom-dev libassimp-dev \ python3-dev python3-numpy这里有个容易踩的坑libeigen3-dev装了之后Eigen 头文件在/usr/include/eigen3/Eigen但有些库会找/usr/include/Eigen编译时如果报找不到 Eigen可以用软链接处理sudo ln -s /usr/include/eigen3/Eigen /usr/include/EigenPython 绑定还依赖eigenpy这个库它是 Eigen 与 NumPy 之间的桥。源码编译 Pinocchio 时子模块会拉取 eigenpy但如果你想单独装最新版也可以先conda install -c conda-forge eigenpy或者自己编译。依赖这块我的原则是能用系统包管理器解决的绝不去手动编译除非你要对 Pinocchio 本体做二次开发。3. 三条安装路线conda、pip、源码编译的实测记录3.1 conda 路线最省心适合多数人如果你的项目里已经用 conda 管理 Python 环境那 Pinocchio 的安装简单到像抄作业conda create -n pinocchio_env python3.10 -y conda activate pinocchio_env conda install -c conda-forge pinocchio想快一点可以把 conda 换成 mambamamba install -c conda-forge pinocchioconda 路线最大优势是不仅装好了 Python 绑定还把 C 库、Boost、Eigen、eigenpy 这些原生依赖一并处理了不需要你手动管LD_LIBRARY_PATH。我建议任何以 Python 使用为主的人闭眼走这条线。装完之后检查python -c import pinocchio as pin; print(pin.__version__)如果能看到版本号那么恭喜最难的环节已经过了。这个环境里你后面还可以装crocoddyl、example-robot-data形成一套完整的机器人算法环境。3.2 pip 安装与其背后的兼容性逻辑pip 路线适合你不想为单个库单独建 conda 环境的情况pip install pin注意包名是pin不是pinocchio。PyPI 上那个叫pinocchio的包另有其人跟机器人动力学毫无关系。我当时第一次就装错了import pinocchio直接给我导出一个完全不知道是什么的模块浪费了二十分钟排查——这是一个很典型的库名和包名不一致坑。pip 安装的 Pinocchio 本质上是官方或社区预编译好的 wheel它会自带对应版本的 Eigen、eigenpy 等二进制依赖。优点是快缺点是它对系统里其他库的版本有隐式要求一旦你系统里有另一套 Boost 或者 OpenMP 版本可能出现undefined symbol这类运行时错误。因此 pip 装完后最好先跑一遍导入测试确认pin.rnea这些函数能正常调用再往项目里铺开用。3.3 源码编译二次开发者的必经之路源码编译是三个方案里最麻烦但也是自由度最高的。什么时候需要走这条路线三种情况一是要修改 Pinocchio 源码本身二是需要和特定版本的其他库比如定制版 hpp-fcl联动三是你需要开启一些发行包默认不开的 CMake 选项。完整过程分四步。第一步克隆仓库。这里必须--recursive因为 submodule 里拉着 eigenpy、hpp-fcl 等一堆东西git clone --recursive https://github.com/stack-of-tasks/pinocchio.git cd pinocchio如果克隆到一半断掉用下面的命令补齐子模块git submodule update --init --recursive第二步创建 build 目录并配置 CMakemkdir build cd build cmake .. \ -DCMAKE_BUILD_TYPERelease \ -DCMAKE_INSTALL_PREFIX$HOME/.local \ -DBUILD_PYTHON_INTERFACEON \ -DBUILD_TESTINGOFF \ -DBUILD_WITH_COLLISION_SUPPORTON \ -DBUILD_WITH_OPENMP_SUPPORTON解释几个选项CMAKE_INSTALL_PREFIX建议装到$HOME/.local而不是系统/usr/local这样以后卸载和升级都干净不会污染系统路径也避免和系统其他软件冲突BUILD_PYTHON_INTERFACE必须为 ON否则装完只有 C 库没有 Python 绑定BUILD_WITH_COLLISION_SUPPORT打开后可以配合 hpp-fcl 做碰撞检测做运动规划会用到。第三步编译安装make -j$(nproc) make install-j$(nproc)会调满你所有 CPU 核虚拟机里如果只有 2 核可以写成make -j2别硬调大然后看着电脑卡死。第四步设置环境变量。源码编译默认不会把 Python 包路径写入系统site-packages所以需要手动加export PATH$HOME/.local/bin:$PATH export PYTHONPATH$HOME/.local/lib/python3.10/site-packages:$PYTHONPATH export LD_LIBRARY_PATH$HOME/.local/lib:$LD_LIBRARY_PATH export PKG_CONFIG_PATH$HOME/.local/lib/pkgconfig:$PKG_CONFIG_PATHPython 后缀根据你实际用的版本调整3.8 就写python3.83.11 就写python3.11。建议把这四行写进~/.bashrc一劳永逸。三条路线对比汇总安装方式难度适用场景需要手动配环境变量conda最简单Python 开发、算法验证不需要pip简单已有 Python 环境、快速使用偶尔需要源码编译较复杂二次开发、定制编译选项、C 项目需要4. 装完怎么验证跑通逆动力学与质量矩阵才算数4.1 import 测试与环境变量排查安装完成不等于能用。我见过太多人安装时很顺利一写代码就 import 报错。所以验证环节别省先做一个最小测试python -c import pinocchio as pin; print(Pinocchio version:, pin.__version__)如果报ModuleNotFoundError: No module named pinocchio说明 Python 解释器找不到模块多半是PYTHONPATH没生效或者 conda 环境没激活。此时回头检查环境变量用下面的命令看看 Python 搜索路径里有没有 pinocchiopython -c import sys; print(\n.join(sys.path))如果模块路径在里面但还报错比如ImportError: libpinocchio.so: cannot open shared object file那就是 C 动态库的搜索路径问题把LD_LIBRARY_PATH指到 Lib 目录再用ldd $(python -c import pinocchio; print(pinocchio.__file__))检查缺哪些依赖。4.2 用 URDF 模型跑一次逆动力学计算导入成功只是第一步。我建议你立刻跑一个真实的动力学计算别等着写到项目里才发现问题。先准备一个最简 URDF 文件保存为planar_2r.urdf?xml version1.0? robot nameplanar_2r link namebase/ link namelink1 inertial origin xyz0.5 0 0 rpy0 0 0/ mass value1.0/ inertia ixx0.01 ixy0 ixz0 iyy0.01 iyz0 izz0.01/ /inertial /link link namelink2 inertial origin xyz0.5 0 0 rpy0 0 0/ mass value0.8/ inertia ixx0.008 ixy0 ixz0 iyy0.008 iyz0 izz0.008/ /inertial /link joint namejoint1 typerevolute parent linkbase/ child linklink1/ origin xyz0 0 0 rpy0 0 0/ axis xyz0 0 1/ limit lower-3.14159 upper3.14159 effort100 velocity10/ /joint joint namejoint2 typerevolute parent linklink1/ child linklink2/ origin xyz1 0 0 rpy0 0 0/ axis xyz0 0 1/ limit lower-3.14159 upper3.14159 effort100 velocity10/ /joint /robot然后写一个短的 Python 脚本测试import pinocchio as pin import numpy as np model, collision_model, visual_model pin.buildModelsFromUrdf( planar_2r.urdf ) data model.createData() print(model.nq , model.nq, model.nv , model.nv) q pin.neutral(model) v np.zeros(model.nv) a np.zeros(model.nv) pin.forwardKinematics(model, data, q) print(tool position:, data.oMi[model.njoints - 1].translation.T) tau pin.rnea(model, data, q, v, a) print(gravity compensation torques:, tau) M pin.crba(model, data, q) print(mass matrix:\n, M)如果tool position打印出合理的三维坐标tau能算出非零重力项M是一个 2x2 对称矩阵那才说明 Pinocchio 真的在你的机器上完整工作了。顺便说一句model.nq是关节配置空间的维度model.nv是切空间维度对大多数关节两者相等但有浮动基座的时候就不一样了这个细节后面做四足机器人会用到。4.3 C 侧编译示例程序如果你以后要在 C 项目里集成还要验证 C 接口。保存下面这段代码为test_pin.cpp#include pinocchio/parsers/urdf.hpp #include pinocchio/algorithm/joint-configuration.hpp #include pinocchio/algorithm/rnea.hpp #include pinocchio/algorithm/crba.hpp #include pinocchio/algorithm/kinematics.hpp #include iostream int main() { pinocchio::Model model; pinocchio::urdf::buildModel(planar_2r.urdf, model); pinocchio::Data data(model); Eigen::VectorXd q pinocchio::neutral(model); Eigen::VectorXd v Eigen::VectorXd::Zero(model.nv); Eigen::VectorXd a Eigen::VectorXd::Zero(model.nv); Eigen::VectorXd tau pinocchio::rnea(model, data, q, v, a); std::cout tau tau.transpose() std::endl; pinocchio::crba(model, data, q); std::cout M std::endl data.M std::endl; pinocchio::forwardKinematics(model, data, q); std::cout tool position data.oMi[model.njoints - 1].translation().transpose() std::endl; return 0; }用 CMake 组织更规范CMakeLists.txt这样写cmake_minimum_required(VERSION 3.10) project(PinocchioTest) find_package(pinocchio REQUIRED) add_executable(test_pin test_pin.cpp) target_link_libraries(test_pin PRIVATE pinocchio::pinocchio)编译运行mkdir -p build_cpp cd build_cpp cmake .. -DCMAKE_PREFIX_PATH$HOME/.local make ./test_pin生成M矩阵应该与 Python 侧一致。跨语言验证一致的这一步很重要很多人在 Python 里调通就开心了结果 C 里编译不过最后才发现find_package的路径没配好。5. 安装路上的高发坑从 import 失败到 URDF 加载报错5.1 Python 接口 import 失败的第一现场我知道安装库这种事报错才是常态。先总结几个高频场景。第一个ModuleNotFoundError。这个最简单就是解释器没找到模块。解决方案就两条激活正确的 conda 环境或者检查PYTHONPATH。我之前犯过的错误是在 conda 环境里 pip 安装但 pip 指向了系统 Python 而不是 conda Python最后模块装进了系统 site-packages当前环境自然找不到。查看 pip 属于哪个 Pythonwhich pip如果显示/usr/bin/pip而不是/home/xxx/miniconda3/envs/pinocchio_env/bin/pip那就说明环境激活状态不对。第二个ImportError: libpython3.10.so.1.0: cannot open shared object file。这种一般是源码编译时依赖了某个 Python 版本运行时又切换到另一个版本导致的。解决方案是把编译时的 Python 路径加入LD_LIBRARY_PATHexport LD_LIBRARY_PATH/usr/lib/x86_64-linux-gnu:$LD_LIBRARY_PATH或者干脆重新编译并指定 Python 版本。第三个undefined symbol: _ZNK5boost...这是典型的多版本 Boost 混用冲突。我没有特别好的解法只能建议你开一个全新干净的环境因为追溯哪个 .so 文件加载了哪份 Boost 会非常痛苦时间成本不划算。5.2 URDF 加载报错的真实原因与定位方法buildModelsFromUrdf直接抛异常是新手最容易懵的时刻。我把它分成三类。第一类文件路径问题。URDF 里的 mesh 标签如果写了绝对路径移动到别的机器上就废了写相对路径你又必须保证运行时的当前工作目录正确。推荐的做法是统一用package://风格配合package_dirs参数或者干脆写一个ROBOT_MODEL_DIR环境变量统一管理模型路径。第二类URDF 语法标签不合法。Pinocchio 的解析器对 URDF 的容错率比 MoveIt 低比如缺少inertial或者 inertia 张量不是严格对称正定的它会直接报错。遇到这类问题先别怀疑库用check_urdf命令检查一下文件本身sudo apt install liburdfdom-tools check_urdf planar_2r.urdf第三类自由飞行的浮动基座机器人比如四足、无人机的 URDF 没有定义浮动关节。做这些机器人时URDF 里通常没有world和base之间的连接关节Pinocchio 默认会加一个自由度数为 6 的JointModelFreeFlyer。如果你的代码里对model.nq的假设写死了就会出现奇奇怪怪的越界错误。记住一个口诀URDF 负载导致结果不对先看nq和nv再对模型做pin.neutral(model)。5.3 环境混用导致版本冲突的防御策略最后聊聊防御因为安装问题九成是环境混用造成的。我的三板斧。第一给 Pinocchio 单独建环境。哪怕你已经有常用的 conda 环境也不要直接塞进去。机器人项目依赖版本经常互相打架单独建一个pinocchio_env或robot_algos环境成本极低时间长了你就知道这有多值。第二记录版本号。pin.__version__不能只看个开心建议配合conda env export environment.yml把整个环境的版本锁下来。我自己吃过一次亏同一个项目半年前能跑半年后跑不了了查了半天是 conda 自动升级把 Boost 顶到了不兼容版本。从此所有项目都留下environment.yml快照。第三优先 conda谨慎 pip。非必要不在 conda 环境里用 pip 装原生依赖库因为 conda 的依赖管理只认自己安装的包pip 塞进来的东西它管不了。如果你非要混合请在安装后立即验证关键 API别等到项目结构搭好了才发现底层库换了。最后再分享一点个人的使用习惯我现在不管做 C 还是 Python 项目都会先用pinocchio example-robot-data跑通一个小 demo再动工写业务代码等于给安装环境做了一次体检。安装从来不是难事难的是陌生的错误信息不断打断你的思路。把上面这些坑提前避开你就能把精力放在真正的机器人和算法问题上。
返回列表