|
Mujoco KDL Wrapper
0.2.2
MuJoCo + KDL bridge for robot kinematics and dynamics
|
Full reference for building and installing mj_kdl_wrapper without ROS, as a plain CMake C++ library and/or a Python package. For ROS 2 / colcon, see the ROS 2 Installation Guide.
Instructions target Ubuntu/Debian. CMake checks mjVERSION_HEADER and stops if MJ_KDL_MUJOCO_DIR points at an unsupported MuJoCo release.
| Dependency | Version / source | Notes |
|---|---|---|
| MuJoCo | 3.9.0 from cmake/Versions.cmake | Native library and pinned mujoco Python package must match |
| Orocos KDL | secorolab fork, feature/achd_fixed_joint | Built from source; system liborocos-kdl is not used |
| CMake | >=3.16 | Required to configure the C++ build |
| C++ compiler | C++20-capable | CMAKE_CXX_STANDARD is set to 20 |
| Python | >=3.10 | Required for the Python package |
| scikit-build-core | >=0.11.2 | Python build backend |
| pybind11 | >=2.13 | Python binding build dependency |
doxygen is only needed for the docs target; python3-dev/python3-venv only for the Python package.
A standard CMake project. The default build is self-contained: it downloads MuJoCo, clones and builds the Orocos KDL fork, and (with the menagerie flag) fetches the robot models. No system MuJoCo or KDL is ever used.
What happens during configure/build:
The install is self-contained. Alongside libmj_kdl_wrapper.so, its headers, and the mj_kdl_wrapper CMake package config, the built Orocos KDL fork is installed into the same prefix:
The wrapper is rpath'd to $ORIGIN, so it loads the co-installed KDL without a build tree or LD_LIBRARY_PATH. Consumers:
MuJoCo is intentionally not bundled into the prefix; consumers resolve it from MJ_KDL_MUJOCO_DIR (or the mujoco pip package). Set -DMJ_KDL_INSTALL_BUNDLED_KDL=OFF to keep KDL out of a shared prefix such as /usr/local, where it could shadow a distro KDL - but then the install is no longer self-contained and KDL must be provided some other way.
Each dependency is fetched by default, or can point at something you already have:
| To... | Set |
|---|---|
| Use an existing MuJoCo install | -DMJ_KDL_MUJOCO_DIR=/opt/mujoco-3.9.0 |
| Override the MuJoCo download URL | -DMJ_KDL_MUJOCO_URL=<url> |
| Skip the MuJoCo download | -DMJ_KDL_FETCH_MUJOCO=OFF (then set MJ_KDL_MUJOCO_DIR) |
| Clone the KDL fork somewhere specific | -DMJ_KDL_OROCOS_KDL_DIR=~/src/orocos_kinematics_dynamics |
| Build a different KDL branch/tag | -DMJ_KDL_OROCOS_KDL_GIT_TAG=<ref> |
| Reuse a prebuilt KDL by prefix | -DMJ_KDL_OROCOS_KDL_INSTALL_DIR=$HOME/ws |
| Consume KDL via its CMake package | -DMJ_KDL_OROCOS_KDL_FROM_PACKAGE=ON |
| Keep bundled KDL out of the install prefix | -DMJ_KDL_INSTALL_BUNDLED_KDL=OFF |
| Fetch Menagerie models | -DMJ_KDL_FETCH_MENAGERIE=ON |
| Choose build / install locations | cmake -B <build-dir> -DCMAKE_INSTALL_PREFIX=<prefix> |
KDL precedence when more than one is set: MJ_KDL_OROCOS_KDL_FROM_PACKAGE > MJ_KDL_OROCOS_KDL_INSTALL_DIR > the in-tree build (MJ_KDL_OROCOS_KDL_DIR / MJ_KDL_FETCH_OROCOS_KDL).
The default build bundles a private KDL, which is correct for a single project. When several projects need KDL, build the fork once into a shared prefix and point all of them at it, so exactly one liborocos-kdl exists (no duplicate copies or rebuilds):
MJ_KDL_OROCOS_KDL_FROM_PACKAGE=ON is the equivalent when the shared KDL is on CMAKE_PREFIX_PATH as a CMake package rather than a known prefix - this is how the ROS 2 workflow shares one KDL across a colcon overlay.
pip install builds the extension, bundles MuJoCo's matching shared library dependency, the secorolab Orocos KDL fork, and PyKDL, and pins mujoco==3.9.0. The build is isolated and self-contained - it does not reuse any C++ build tree.
PyKDL is bundled inside the wheel as a top-level extension module. It imports as PyKDL but does not appear as a separate package in pip list / uv pip list.
Verify:
All optional, passed via scikit-build-core:
| To... | Add |
|---|---|
| Editable install (dev), auto-rebuild on import | uv pip install -e . --config-settings=editable.rebuild=true |
| Put the build dir outside the source tree | --config-settings=build-dir=/path/build_py/{wheel_tag} |
| Build KDL from an existing checkout | --config-settings=cmake.define.MJ_KDL_OROCOS_KDL_DIR=/path |
| Reuse a prebuilt KDL+PyKDL prefix (skip bundling) | --config-settings=cmake.define.MJ_KDL_OROCOS_KDL_INSTALL_DIR=/prefix |
The shared-KDL option needs a prefix that also ships PyKDL; a C++-only install prefix has KDL but no PyKDL, so the default (bundle) is right for standalone use.
The examples ship in the wheel; mj-kdl-fetch-examples copies them out as an examples/ directory. The scripts resolve MuJoCo Menagerie models and bundled assets from the user cache, populated once by mj-kdl-fetch-menagerie, so the copied scripts run from any directory:
Model resolution, environment variables, and using other model sources are documented in the Python Bindings API Guide.
Open build/docs/html/index.html. The docs include the C++ headers, C++ examples, Markdown guides, Python stubs, and Python examples, and link KDL types locally via a generated kdl.tag. Requires doxygen.
Paths / sources:
| Flag | Default | Description |
|---|---|---|
| MJ_KDL_MUJOCO_DIR | ~/.cache/mj_kdl_wrapper/mujoco-${MJ_KDL_MUJOCO_VERSION} | MuJoCo location: download destination, or an existing install to use |
| MJ_KDL_FETCH_MUJOCO | ON | Download MuJoCo into the cache when MJ_KDL_MUJOCO_DIR is not present |
| MJ_KDL_MUJOCO_URL | (release) | MuJoCo archive URL to download |
| MJ_KDL_FETCH_OROCOS_KDL | ON | Clone and build the secorolab Orocos KDL fork (the only KDL used) |
| MJ_KDL_OROCOS_KDL_GIT_REPOSITORY | secorolab fork | Orocos KDL git source to build |
| MJ_KDL_OROCOS_KDL_GIT_TAG | feature/achd_fixed_joint | Orocos KDL branch/tag to build |
| MJ_KDL_OROCOS_KDL_DIR | third_party/orocos_kinematics_dynamics | Fork source/clone destination; built in place if present, else cloned here when fetch is ON |
| MJ_KDL_OROCOS_KDL_INSTALL_DIR | (empty) | Pre-installed Orocos KDL prefix to consume (skips building and bundling the fork) |
| MJ_KDL_OROCOS_KDL_FROM_PACKAGE | OFF | Consume Orocos KDL via find_package(orocos_kdl) on CMAKE_PREFIX_PATH; skips building and bundling the fork |
| MJ_KDL_FETCH_MENAGERIE | OFF | Download MuJoCo Menagerie models |
| MJ_KDL_MENAGERIE_DIR | ~/.cache/mj_kdl_wrapper/menagerie | Menagerie location / MJ_KDL_FETCH_MENAGERIE destination |
Build toggles:
| Flag | Default | Description |
|---|---|---|
| BUILD_RECORDER | ON | Enable VideoRecorder (EGL + ffmpeg headless recording) |
| BUILD_EXAMPLES | ON | Build the src/examples/ex_* programs |
| BUILD_TESTS | ON | Build and register GoogleTest tests with CTest |
| BUILD_DOCS | OFF | Generate Doxygen HTML docs (cmake --build build --target docs) |
| BUILD_PYTHON_BINDINGS | OFF | Build the pybind11 extension (driven by the Python build) |
| MJ_KDL_INSTALL_CPP_PACKAGE | ON (OFF under scikit-build) | Install the C++ library, headers, and CMake package config |
| MJ_KDL_INSTALL_BUNDLED_KDL | ON | Install the built Orocos KDL fork into the prefix so the install is self-contained. No effect with MJ_KDL_OROCOS_KDL_INSTALL_DIR / MJ_KDL_OROCOS_KDL_FROM_PACKAGE |
| SHOW_EQUALITY_PANEL | OFF | Show the Simulate UI Equality section |
| SHOW_GROUP_PANEL | OFF | Show the Simulate UI Group enable section |