embodik 0.1.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. embodik-0.1.1/.gitattributes +36 -0
  2. embodik-0.1.1/.github/workflows/ci.yml +125 -0
  3. embodik-0.1.1/.github/workflows/docs.yml +52 -0
  4. embodik-0.1.1/.github/workflows/release.yml +56 -0
  5. embodik-0.1.1/.gitignore +88 -0
  6. embodik-0.1.1/CHANGELOG.md +49 -0
  7. embodik-0.1.1/CMakeLists.txt +135 -0
  8. embodik-0.1.1/CONTRIBUTING.md +160 -0
  9. embodik-0.1.1/LICENSE +21 -0
  10. embodik-0.1.1/MANIFEST.in +21 -0
  11. embodik-0.1.1/PKG-INFO +309 -0
  12. embodik-0.1.1/README.md +265 -0
  13. embodik-0.1.1/cpp_core/include/embodik/constraints.hpp +51 -0
  14. embodik-0.1.1/cpp_core/include/embodik/ik_baseline.hpp +726 -0
  15. embodik-0.1.1/cpp_core/include/embodik/kinematics_solver.hpp +356 -0
  16. embodik-0.1.1/cpp_core/include/embodik/robot_model.hpp +320 -0
  17. embodik-0.1.1/cpp_core/include/embodik/tasks.hpp +586 -0
  18. embodik-0.1.1/cpp_core/include/embodik/types.hpp +116 -0
  19. embodik-0.1.1/cpp_core/src/kinematics_solver.cpp +978 -0
  20. embodik-0.1.1/cpp_core/src/robot_model.cpp +418 -0
  21. embodik-0.1.1/cpp_core/src/tasks.cpp +833 -0
  22. embodik-0.1.1/docs/api/index.md +79 -0
  23. embodik-0.1.1/docs/api/kinematics_solver.md +81 -0
  24. embodik-0.1.1/docs/api/robot_model.md +66 -0
  25. embodik-0.1.1/docs/api/tasks.md +94 -0
  26. embodik-0.1.1/docs/api/utils.md +26 -0
  27. embodik-0.1.1/docs/api/visualization.md +59 -0
  28. embodik-0.1.1/docs/development.md +157 -0
  29. embodik-0.1.1/docs/examples/basic_ik.md +56 -0
  30. embodik-0.1.1/docs/examples/index.md +70 -0
  31. embodik-0.1.1/docs/examples/multi_task_ik.md +81 -0
  32. embodik-0.1.1/docs/index.md +56 -0
  33. embodik-0.1.1/docs/installation.md +264 -0
  34. embodik-0.1.1/docs/quickstart.md +147 -0
  35. embodik-0.1.1/docs/transforms.md +530 -0
  36. embodik-0.1.1/examples/01_basic_ik_simple.py +499 -0
  37. embodik-0.1.1/examples/02_collision_aware_IK.py +837 -0
  38. embodik-0.1.1/examples/example_helpers/__init__.py +6 -0
  39. embodik-0.1.1/examples/example_helpers/dual_arm_ik_helper.py +381 -0
  40. embodik-0.1.1/examples/example_helpers/limit_profiles/alpha_extended.yaml +23 -0
  41. embodik-0.1.1/examples/example_helpers/limit_profiles/alpha_extended_all.yaml +46 -0
  42. embodik-0.1.1/examples/example_helpers/limit_profiles/beta_uniform_plus21.yaml +39 -0
  43. embodik-0.1.1/examples/robot_model_example.py +183 -0
  44. embodik-0.1.1/examples/utils/__init__.py +14 -0
  45. embodik-0.1.1/examples/utils/robot_models.py +355 -0
  46. embodik-0.1.1/examples/visualization_example.py +245 -0
  47. embodik-0.1.1/mkdocs.yml +85 -0
  48. embodik-0.1.1/pixi.lock +4998 -0
  49. embodik-0.1.1/pixi.toml +89 -0
  50. embodik-0.1.1/pyproject.toml +104 -0
  51. embodik-0.1.1/python/embodik/__init__.py +101 -0
  52. embodik-0.1.1/python/embodik/_runtime_deps.py +47 -0
  53. embodik-0.1.1/python/embodik/cli.py +354 -0
  54. embodik-0.1.1/python/embodik/examples/__init__.py +38 -0
  55. embodik-0.1.1/python/embodik/examples/basic_ik.py +56 -0
  56. embodik-0.1.1/python/embodik/examples/robot_model.py +41 -0
  57. embodik-0.1.1/python/embodik/robot_visualizer.py +304 -0
  58. embodik-0.1.1/python/embodik/utils.py +369 -0
  59. embodik-0.1.1/python/embodik/viser_helpers.py +464 -0
  60. embodik-0.1.1/python/embodik/visualization.py +457 -0
  61. embodik-0.1.1/python/embodik/visualization_pinocchio.py +455 -0
  62. embodik-0.1.1/python_bindings/CMakeLists.txt +112 -0
  63. embodik-0.1.1/python_bindings/src/bindings.cpp +191 -0
  64. embodik-0.1.1/python_bindings/src/kinematics_solver_bindings.cpp +190 -0
  65. embodik-0.1.1/python_bindings/src/robot_model_bindings.cpp +236 -0
  66. embodik-0.1.1/python_bindings/src/tasks_bindings.cpp +189 -0
  67. embodik-0.1.1/scripts/patch_qhull_cmake.py +141 -0
  68. embodik-0.1.1/scripts/setup_pypirc.sh +43 -0
  69. embodik-0.1.1/scripts/test_cpp_extension.py +44 -0
  70. embodik-0.1.1/scripts/test_extension_direct.py +58 -0
  71. embodik-0.1.1/scripts/test_import.py +60 -0
  72. embodik-0.1.1/scripts/test_python_utils.py +114 -0
  73. embodik-0.1.1/scripts/upload_pypi.sh +26 -0
  74. embodik-0.1.1/scripts/upload_testpypi.sh +22 -0
  75. embodik-0.1.1/scripts/version.py +122 -0
  76. embodik-0.1.1/test/CMakeLists.txt +32 -0
  77. embodik-0.1.1/test/test_embodik.py +665 -0
  78. embodik-0.1.1/test/test_robot_model.cpp +171 -0
  79. embodik-0.1.1/test/test_robot_model.py +222 -0
  80. embodik-0.1.1/test/test_tasks.py +328 -0
@@ -0,0 +1,36 @@
1
+ # Auto detect text files and perform LF normalization
2
+ * text=auto
3
+
4
+ # Explicitly declare text files you want to always be normalized and converted
5
+ # to native line endings on checkout.
6
+ *.py text eol=lf
7
+ *.cpp text eol=lf
8
+ *.hpp text eol=lf
9
+ *.h text eol=lf
10
+ *.cmake text eol=lf
11
+ *.yaml text eol=lf
12
+ *.yml text eol=lf
13
+ *.toml text eol=lf
14
+ *.md text eol=lf
15
+ *.txt text eol=lf
16
+ *.json text eol=lf
17
+
18
+ # Denote all files that are truly binary and should not be modified.
19
+ *.png binary
20
+ *.jpg binary
21
+ *.jpeg binary
22
+ *.gif binary
23
+ *.ico binary
24
+ *.pdf binary
25
+ *.zip binary
26
+ *.tar.gz binary
27
+ *.so binary
28
+ *.dylib binary
29
+ *.dll binary
30
+ *.a binary
31
+ *.obj binary
32
+ *.stl binary
33
+ *.dae binary
34
+ *.dae binary
35
+ *.urdf binary
36
+ *.xacro binary
@@ -0,0 +1,125 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [ main, packaging-and-docs ]
6
+ pull_request:
7
+ branches: [ main, packaging-and-docs ]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ matrix:
14
+ python-version: ["3.8", "3.9", "3.10", "3.11"]
15
+
16
+ steps:
17
+ - name: Checkout code
18
+ uses: actions/checkout@v4
19
+
20
+ - name: Set up Python ${{ matrix.python-version }}
21
+ uses: actions/setup-python@v5
22
+ with:
23
+ python-version: ${{ matrix.python-version }}
24
+
25
+ - name: Install system dependencies
26
+ run: |
27
+ sudo apt-get update
28
+ sudo apt-get install -y \
29
+ build-essential \
30
+ cmake \
31
+ libeigen3-dev \
32
+ pkg-config
33
+
34
+ - name: Install Pinocchio
35
+ run: |
36
+ # Try to install via apt first, fallback to building from source if needed
37
+ sudo apt-get install -y robotpkg-pinocchio || echo "Pinocchio not available via apt, will need manual installation"
38
+
39
+ - name: Install Python dependencies
40
+ run: |
41
+ python -m pip install --upgrade pip
42
+ pip install nanobind scikit-build-core[pyproject]
43
+ pip install pytest pytest-cov
44
+
45
+ - name: Install project dependencies
46
+ run: |
47
+ pip install numpy
48
+
49
+ - name: Build and install package
50
+ run: |
51
+ pip install -e .
52
+ env:
53
+ CMAKE_PREFIX_PATH: ${{ env.CMAKE_PREFIX_PATH }}
54
+
55
+ - name: Run tests
56
+ run: |
57
+ pytest test/ -v
58
+ continue-on-error: true
59
+
60
+ - name: Check code formatting
61
+ run: |
62
+ pip install black isort
63
+ black --check python/ test/ examples/ || true
64
+ isort --check python/ test/ examples/ || true
65
+ continue-on-error: true
66
+
67
+ build:
68
+ runs-on: ubuntu-latest
69
+ strategy:
70
+ matrix:
71
+ python-version: ["3.10", "3.11"]
72
+
73
+ steps:
74
+ - name: Checkout code
75
+ uses: actions/checkout@v4
76
+
77
+ - name: Set up Python ${{ matrix.python-version }}
78
+ uses: actions/setup-python@v5
79
+ with:
80
+ python-version: ${{ matrix.python-version }}
81
+
82
+ - name: Install system dependencies
83
+ run: |
84
+ sudo apt-get update
85
+ sudo apt-get install -y \
86
+ build-essential \
87
+ cmake \
88
+ libeigen3-dev \
89
+ pkg-config
90
+
91
+ - name: Install Python build dependencies
92
+ run: |
93
+ python -m pip install --upgrade pip
94
+ pip install build wheel
95
+
96
+ - name: Build wheel
97
+ run: |
98
+ python -m build --wheel
99
+ continue-on-error: true
100
+
101
+ - name: Verify wheel
102
+ run: |
103
+ pip install dist/*.whl
104
+ continue-on-error: true
105
+
106
+ docs:
107
+ runs-on: ubuntu-latest
108
+ steps:
109
+ - name: Checkout code
110
+ uses: actions/checkout@v4
111
+
112
+ - name: Set up Python
113
+ uses: actions/setup-python@v5
114
+ with:
115
+ python-version: "3.10"
116
+
117
+ - name: Install documentation dependencies
118
+ run: |
119
+ python -m pip install --upgrade pip
120
+ pip install mkdocs-material mkdocstrings[python]
121
+
122
+ - name: Build documentation
123
+ run: |
124
+ mkdocs build --strict
125
+ continue-on-error: true
@@ -0,0 +1,52 @@
1
+ name: Documentation
2
+
3
+ on:
4
+ push:
5
+ branches: [ main ]
6
+ workflow_dispatch:
7
+
8
+ permissions:
9
+ contents: read
10
+ pages: write
11
+ id-token: write
12
+
13
+ concurrency:
14
+ group: "pages"
15
+ cancel-in-progress: false
16
+
17
+ jobs:
18
+ build:
19
+ runs-on: ubuntu-latest
20
+ steps:
21
+ - name: Checkout code
22
+ uses: actions/checkout@v4
23
+
24
+ - name: Install Pixi
25
+ uses: prefix-dev/setup-pixi@v0
26
+
27
+ - name: Build and install package
28
+ run: |
29
+ pixi run install
30
+
31
+ - name: Build documentation
32
+ run: |
33
+ pixi run python -W ignore::DeprecationWarning:hppfcl -m mkdocs build --strict
34
+
35
+ - name: Setup Pages
36
+ uses: actions/configure-pages@v4
37
+
38
+ - name: Upload artifact
39
+ uses: actions/upload-pages-artifact@v3
40
+ with:
41
+ path: ./site
42
+
43
+ deploy:
44
+ environment:
45
+ name: github-pages
46
+ url: ${{ steps.deployment.outputs.page_url }}
47
+ runs-on: ubuntu-latest
48
+ needs: build
49
+ steps:
50
+ - name: Deploy to GitHub Pages
51
+ id: deployment
52
+ uses: actions/deploy-pages@v4
@@ -0,0 +1,56 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - 'v*'
7
+
8
+ jobs:
9
+ build-and-publish:
10
+ runs-on: ubuntu-latest
11
+ permissions:
12
+ contents: write
13
+ id-token: write
14
+
15
+ steps:
16
+ - name: Checkout code
17
+ uses: actions/checkout@v4
18
+
19
+ - name: Set up Python
20
+ uses: actions/setup-python@v5
21
+ with:
22
+ python-version: "3.10"
23
+
24
+ - name: Install system dependencies
25
+ run: |
26
+ sudo apt-get update
27
+ sudo apt-get install -y \
28
+ build-essential \
29
+ cmake \
30
+ libeigen3-dev \
31
+ pkg-config
32
+
33
+ - name: Install build dependencies
34
+ run: |
35
+ python -m pip install --upgrade pip
36
+ pip install build twine
37
+
38
+ - name: Build source distribution and wheels
39
+ run: |
40
+ python -m build
41
+
42
+ - name: Publish to PyPI
43
+ uses: pypa/gh-action-pypi-publish@release/v1
44
+ with:
45
+ packages-dir: dist/
46
+
47
+ - name: Create GitHub Release
48
+ uses: actions/create-release@v1
49
+ env:
50
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
51
+ with:
52
+ tag_name: ${{ github.ref }}
53
+ release_name: Release ${{ github.ref }}
54
+ draft: false
55
+ prerelease: false
56
+ continue-on-error: true
@@ -0,0 +1,88 @@
1
+ # Python build artifacts
2
+ python_bindings/*.cmake
3
+ python_bindings/CMakeFiles/
4
+ python_bindings/build/
5
+ python_bindings/*.a
6
+ python_bindings/swift_ik_py/
7
+ python_bindings/embodik_py/
8
+ test/__pycache__/
9
+ examples/__pycache__/
10
+ examples/**/__pycache__/
11
+ python_bindings/Makefile
12
+ python_bindings/CMakeCache.txt
13
+ python/embodik/__pycache__/
14
+ *.pyc
15
+ __pycache__/
16
+
17
+ # Ignore generated type stubs and py.typed in build directories
18
+ python_bindings/**/*.pyi
19
+ python_bindings/**/py.typed
20
+ build/**/*.pyi
21
+ build/**/py.typed
22
+
23
+ # CMake build artifacts (root directory)
24
+ CMakeCache.txt
25
+ CMakeFiles/
26
+ CMakeInit.txt
27
+ cmake_install.cmake
28
+ build.ninja
29
+ .cmake/
30
+ cmake/
31
+
32
+ # Ninja build system files
33
+ .ninja_deps
34
+ .ninja_log
35
+ *.ninja
36
+
37
+ # scikit-build-core artifacts
38
+ .skbuild/
39
+ .skbuild-info.json
40
+ dist/
41
+ *.egg-info/
42
+
43
+ # Build directories
44
+ build/
45
+ install/
46
+
47
+ # Compiled libraries and binaries
48
+ *.so
49
+ *.a
50
+ *.dylib
51
+ *.dll
52
+ *.exe
53
+
54
+ # Pixi lock file - COMMIT THIS for reproducibility (ensures consistent environments)
55
+ # Both pixi.toml and pixi.lock should be version-controlled per Pixi documentation
56
+ # Only ignore the .pixi/ directory (environment cache), not the lock file
57
+ .pixi/
58
+
59
+ # Data files
60
+ *.h5
61
+ *.npz
62
+ *.pkl
63
+ reachability_maps/
64
+ robot_models_urdf/
65
+ tmp_reach_test/
66
+
67
+ # Documentation build artifacts
68
+ docs/_build/
69
+ docs/.doctrees/
70
+ site/
71
+
72
+ # Temporary files
73
+ *.diff
74
+ *.tmp
75
+ *.swp
76
+ *~
77
+
78
+ # Ignore all Markdown files except README.md, docs, and important project files
79
+ *.md
80
+ !README.md
81
+ !docs/**/*.md
82
+ !plan_docs/**/*.md
83
+ !CHANGELOG.md
84
+ !CONTRIBUTING.md
85
+ !LICENSE
86
+
87
+ # Robot models
88
+ examples/robot_models*/**
@@ -0,0 +1,49 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [0.1.1] - 2025-01-09
9
+
10
+ ### Added
11
+ - **PyPI Publishing**: Full wheel building and publishing workflow for TestPyPI and PyPI
12
+ - **`embodik-sanitize-env` CLI**: Helper to sanitize `LD_LIBRARY_PATH` for clean pip installs
13
+ - **`embodik-examples` CLI**: Tool to list and copy examples for pip-installed users
14
+ - **Built-in robot presets**: `panda` and `iiwa` presets work without `robot_presets.yaml`
15
+ - **sdist build support**: Source distribution builds now auto-detect PyPI `pin` wheel's Pinocchio
16
+
17
+ ### Changed
18
+ - Simplified `_runtime_deps.py` - removed complex preloading logic, now just provides `import_pinocchio()` helper
19
+ - Documentation updated to recommend `venv + pip + unset LD_LIBRARY_PATH` as primary user flow
20
+ - ViserVisualizer now uses empty GeometryModel instead of None when collisions disabled
21
+
22
+ ### Fixed
23
+ - Fixed `KeyError: 'pinocchio/frames/universe'` in ViserVisualizer when `load_collisions=False`
24
+ - Fixed RPATH for `_embodik_impl.so` to correctly find `libembodik_core.so`
25
+ - Fixed sdist builds failing to find Pinocchio by auto-detecting `pin` wheel's CMake config
26
+ - Examples now work correctly for pip-installed users via `embodik-examples --copy`
27
+
28
+ ### Dependencies
29
+ - Added `pin>=3.8.0` to build-system requirements for sdist builds
30
+ - Added `pyyaml`, `robot_descriptions`, `viser`, `yourdfpy` to `[examples]` optional dependencies
31
+
32
+ ## [0.1.0] - 2025-12-12
33
+
34
+ ### Added
35
+ - Initial release of embodiK
36
+ - High-performance inverse kinematics solver with hierarchical task resolution
37
+ - Python bindings using nanobind
38
+ - Support for multiple task types (FrameTask, PostureTask, COMTask, JointTask, MultiJointTask)
39
+ - Position and velocity IK solving
40
+ - Optional visualization tools using Viser
41
+ - Comprehensive test suite
42
+ - Example scripts demonstrating various use cases
43
+
44
+ ### Technical Details
45
+ - C++17 core library built on Pinocchio and Eigen3
46
+ - Python 3.8+ support
47
+ - Linux x86_64 support
48
+ - CMake-based build system
49
+ - scikit-build-core for Python packaging
@@ -0,0 +1,135 @@
1
+ cmake_minimum_required(VERSION 3.16)
2
+ project(embodik VERSION 0.1.1)
3
+
4
+ # Python is used to auto-discover Pinocchio (PyPI `pin`) CMake config during sdist builds.
5
+ find_package(Python REQUIRED COMPONENTS Interpreter)
6
+
7
+ # C++ standard
8
+ set(CMAKE_CXX_STANDARD 17)
9
+ set(CMAKE_CXX_STANDARD_REQUIRED ON)
10
+
11
+ # Options
12
+ option(BUILD_PYTHON_BINDINGS "Build Python bindings" ON)
13
+ option(BUILD_TESTS "Build unit tests" ON)
14
+ option(BUILD_EXAMPLES "Build examples" ON)
15
+
16
+ # Find dependencies
17
+ find_package(Eigen3 3.3 REQUIRED NO_MODULE)
18
+
19
+ # If the user doesn't have a system Pinocchio install, try to locate the CMake config
20
+ # shipped with the PyPI `pin` wheel (import name: `pinocchio`).
21
+ #
22
+ # This helps `pip install` from sdist (when a wheel isn't available) in a plain venv.
23
+ if(NOT DEFINED pinocchio_DIR AND NOT DEFINED ENV{pinocchio_DIR})
24
+ execute_process(
25
+ COMMAND "${Python_EXECUTABLE}" -c
26
+ "import pathlib, sys\n"
27
+ "try:\n"
28
+ " import pinocchio\n"
29
+ "except Exception:\n"
30
+ " sys.exit(1)\n"
31
+ "p = pathlib.Path(pinocchio.__file__).resolve()\n"
32
+ "# .../cmeel.prefix/lib/pythonX/site-packages/pinocchio/__init__.py\n"
33
+ "prefix = p.parents[4]\n"
34
+ "print(str(prefix))\n"
35
+ RESULT_VARIABLE _pin_prefix_rc
36
+ OUTPUT_VARIABLE _pin_prefix
37
+ OUTPUT_STRIP_TRAILING_WHITESPACE
38
+ )
39
+ if(_pin_prefix_rc EQUAL 0 AND _pin_prefix)
40
+ message(STATUS "Detected PyPI `pin` prefix: ${_pin_prefix}")
41
+ # Prefer the `pin` wheel's CMake packages over any local Pinocchio installs.
42
+ list(PREPEND CMAKE_PREFIX_PATH "${_pin_prefix}")
43
+ # Force pinocchio_DIR to the wheel-provided config to avoid accidentally
44
+ # picking up a locally-built Pinocchio (which can bake in incompatible Boost SONAMEs).
45
+ set(pinocchio_DIR "${_pin_prefix}/lib/cmake/pinocchio" CACHE PATH "Pinocchio CMake package directory" FORCE)
46
+ message(STATUS "Forcing pinocchio_DIR=${pinocchio_DIR}")
47
+ endif()
48
+ endif()
49
+
50
+ find_package(pinocchio REQUIRED)
51
+
52
+ # Add compile options
53
+ if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
54
+ add_compile_options(-Wall -Wextra -Wpedantic)
55
+ endif()
56
+
57
+ # Create main library
58
+ add_library(embodik_core SHARED
59
+ cpp_core/src/robot_model.cpp
60
+ cpp_core/src/tasks.cpp
61
+ cpp_core/src/kinematics_solver.cpp
62
+ )
63
+
64
+ target_include_directories(embodik_core PUBLIC
65
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/cpp_core/include>
66
+ $<INSTALL_INTERFACE:include>
67
+ )
68
+
69
+ # For inplace editable installs, copy core library to python/embodik directory
70
+ # Always copy for editable installs (editable.mode = "inplace" in pyproject.toml)
71
+ add_custom_command(TARGET embodik_core POST_BUILD
72
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different
73
+ $<TARGET_FILE:embodik_core>
74
+ "${CMAKE_CURRENT_SOURCE_DIR}/python/embodik/"
75
+ COMMENT "Copying core library to python/embodik for editable install"
76
+ )
77
+
78
+ target_link_libraries(embodik_core PUBLIC
79
+ Eigen3::Eigen
80
+ pinocchio::pinocchio
81
+ )
82
+
83
+ # Python bindings
84
+ if(BUILD_PYTHON_BINDINGS)
85
+ add_subdirectory(python_bindings)
86
+ endif()
87
+
88
+ # Tests
89
+ if(BUILD_TESTS)
90
+ enable_testing()
91
+ if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/test/CMakeLists.txt")
92
+ add_subdirectory(test)
93
+ endif()
94
+ endif()
95
+
96
+ # Examples
97
+ if(BUILD_EXAMPLES)
98
+ if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/examples/CMakeLists.txt")
99
+ add_subdirectory(examples)
100
+ endif()
101
+ endif()
102
+
103
+ # Installation
104
+ install(TARGETS embodik_core
105
+ EXPORT embodik_targets
106
+ LIBRARY DESTINATION lib
107
+ ARCHIVE DESTINATION lib
108
+ RUNTIME DESTINATION bin
109
+ )
110
+
111
+ install(DIRECTORY cpp_core/include/
112
+ DESTINATION include
113
+ )
114
+
115
+ install(EXPORT embodik_targets
116
+ FILE embodik_targets.cmake
117
+ NAMESPACE embodik::
118
+ DESTINATION lib/cmake/embodik
119
+ )
120
+
121
+ # Python package installation
122
+ # Note: scikit-build-core handles Python package installation via wheel.packages
123
+ # The extension module is installed by python_bindings/CMakeLists.txt
124
+ # Python source files are included via wheel.packages in pyproject.toml
125
+
126
+ # Install examples directory for pip-installed users
127
+ install(DIRECTORY examples/
128
+ DESTINATION share/embodik/examples
129
+ FILES_MATCHING
130
+ PATTERN "*.py"
131
+ PATTERN "*.yaml"
132
+ PATTERN "*.md"
133
+ PATTERN "__pycache__" EXCLUDE
134
+ PATTERN "*.pyc" EXCLUDE
135
+ )
@@ -0,0 +1,160 @@
1
+ # Contributing to embodiK
2
+
3
+ Thank you for your interest in contributing to embodiK! This document provides guidelines and instructions for contributing.
4
+
5
+ ## Code of Conduct
6
+
7
+ By participating in this project, you agree to maintain a respectful and inclusive environment for all contributors.
8
+
9
+ ## How to Contribute
10
+
11
+ ### Reporting Issues
12
+
13
+ Before creating an issue, please:
14
+ 1. Check if the issue already exists
15
+ 2. Use a clear, descriptive title
16
+ 3. Provide a minimal example that reproduces the issue
17
+ 4. Include your environment details (OS, Python version, etc.)
18
+
19
+ ### Submitting Pull Requests
20
+
21
+ 1. **Fork the repository** and create a branch from `main`
22
+ 2. **Make your changes** following our coding standards
23
+ 3. **Add tests** for new functionality
24
+ 4. **Update documentation** if needed
25
+ 5. **Run tests** locally before submitting
26
+ 6. **Submit a pull request** with a clear description
27
+
28
+ ### Development Setup
29
+
30
+ #### Option 1: Using Pixi (Recommended)
31
+
32
+ Pixi provides a reproducible development environment with all dependencies managed automatically.
33
+
34
+ 1. Install Pixi:
35
+ ```bash
36
+ curl -fsSL https://pixi.sh/install.sh | bash
37
+ ```
38
+
39
+ 2. Clone your fork:
40
+ ```bash
41
+ git clone https://github.com/YOUR_USERNAME/embodik.git
42
+ cd embodik
43
+ ```
44
+
45
+ 3. Install the package in development mode:
46
+ ```bash
47
+ pixi run install
48
+ # Or with auto-rebuild on import:
49
+ pixi run install-rebuild
50
+ ```
51
+
52
+ 4. Activate the pixi environment:
53
+ ```bash
54
+ pixi shell
55
+ ```
56
+
57
+ All system dependencies (CMake, Eigen, Pinocchio, etc.) are automatically managed by pixi.
58
+
59
+ #### Option 2: Manual Setup
60
+
61
+ 1. Clone your fork:
62
+ ```bash
63
+ git clone https://github.com/YOUR_USERNAME/embodik.git
64
+ cd embodik
65
+ ```
66
+
67
+ 2. Install system dependencies:
68
+ - CMake 3.16+
69
+ - C++17 compiler (GCC 7+, Clang 5+)
70
+ - Eigen3 development headers (`libeigen3-dev` on Ubuntu)
71
+ - Pinocchio library
72
+
73
+ 3. Install in development mode:
74
+ ```bash
75
+ pip install -e ".[dev]"
76
+ ```
77
+
78
+ ### Coding Standards
79
+
80
+ - **Python**: Follow PEP 8 style guide
81
+ - **C++**: Follow the existing code style (C++17 standard)
82
+ - **Documentation**: Use docstrings for all public functions/classes
83
+ - **Tests**: Write tests for new features and bug fixes
84
+
85
+ ### Running Tests
86
+
87
+ **With Pixi:**
88
+ ```bash
89
+ pixi run test
90
+ pixi run test-verbose
91
+ pixi run test-cov # With coverage (requires dev feature)
92
+ ```
93
+
94
+ **Without Pixi:**
95
+ ```bash
96
+ # Run Python tests
97
+ pytest
98
+
99
+ # Run with coverage
100
+ pytest --cov=embodik --cov-report=html
101
+
102
+ # Run C++ tests
103
+ cd build && ctest
104
+ ```
105
+
106
+ ### Code Formatting
107
+
108
+ We use `black` and `isort` for Python code formatting:
109
+
110
+ **With Pixi:**
111
+ ```bash
112
+ pixi run format # Format code
113
+ pixi run lint # Check formatting
114
+ ```
115
+
116
+ **Without Pixi:**
117
+ ```bash
118
+ # Format code
119
+ black python/ test/ examples/
120
+ isort python/ test/ examples/
121
+
122
+ # Check formatting
123
+ black --check python/ test/ examples/
124
+ isort --check python/ test/ examples/
125
+ ```
126
+
127
+ ### Documentation
128
+
129
+ - Update docstrings for any new public APIs
130
+ - Update relevant documentation files in `docs/`
131
+ - Build docs locally to verify:
132
+ ```bash
133
+ # With Pixi
134
+ pixi run docs-serve
135
+
136
+ # Without Pixi
137
+ mkdocs serve
138
+ ```
139
+
140
+ ### Commit Messages
141
+
142
+ Use clear, descriptive commit messages:
143
+ - Start with a verb in imperative mood (e.g., "Add", "Fix", "Update")
144
+ - Keep the first line under 72 characters
145
+ - Add more details in the body if needed
146
+
147
+ Example:
148
+ ```
149
+ Add support for joint limit constraints
150
+
151
+ - Implement joint limit checking in kinematics solver
152
+ - Add tests for limit enforcement
153
+ - Update documentation with examples
154
+ ```
155
+
156
+ ## Questions?
157
+
158
+ Feel free to open an issue for questions or reach out to the maintainers.
159
+
160
+ Thank you for contributing to embodiK!