diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..07fe41c --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# GitHub syntax highlighting +pixi.lock linguist-language=YAML linguist-generated=true diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..fee8002 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,32 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for all configuration options: +# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates + +version: 2 +updates: + - package-ecosystem: "pip" # See documentation for possible values + directory: "/" # Location of package manifests + schedule: + interval: "monthly" + groups: + dev-dependencies: + #try to group all development dependencies updates into a single pr + patterns: + - "black" + - "check-manifest" + - "pre-commit" + - "pylint" + - "pytest" + - "pytest-cov" + - "hypothesis" + - "ruff" + - "coverage" + lib-dependencies: + #try to group all third party library updates into a single pr + patterns: + - "*" + - package-ecosystem: github-actions + directory: / + schedule: + interval: monthly diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..b189825 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,18 @@ +name: Auto-publish + +on: [push, workflow_dispatch] + +jobs: + # Auto-publish when version is increased + publish-job: + # Only publish on `test_pixi` branch + if: github.ref == 'refs/heads/test_pixi' + runs-on: ubuntu-latest + permissions: # Don't forget permissions + contents: write + steps: + - uses: etils-actions/pypi-auto-publish@v1 + with: + pypi-token: ${{ secrets.PYPI_API_TOKEN }} + gh-token: ${{ secrets.GITHUB_TOKEN }} + parse-changelog: true diff --git a/.gitignore b/.gitignore index d1ba6ab..c734617 100644 --- a/.gitignore +++ b/.gitignore @@ -26,6 +26,9 @@ share/python-wheels/ *.egg MANIFEST +# pixi environments +.pixi + # PyInstaller # Usually these files are written by a python script from a template # before PyInstaller builds the exe, so as to inject date/other infos into it. @@ -94,13 +97,6 @@ ipython_config.py # install all needed dependencies. #Pipfile.lock -# poetry -# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. -# This is especially recommended for binary packages to ensure reproducibility, and is more -# commonly ignored for libraries. -# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control -poetry.lock - # pdm # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. #pdm.lock diff --git a/examples/demo_task_space_control.py b/examples/demo_task_space_control.py new file mode 100644 index 0000000..f260705 --- /dev/null +++ b/examples/demo_task_space_control.py @@ -0,0 +1,53 @@ +import time +import numpy as np +from pybullet_robot.bullet_robot import BulletRobot +from pybullet_robot.utils.urdf_utils import get_urdf_from_awesome_robot_descriptions + +from impedance_controllers import CartesianImpedanceController + +NEUTRAL_JOINT_POS = [ + -0.017792060227770554, + -0.7601235411041661, + 0.019782607023391807, + -2.342050140544315, + 0.029840531355804868, + 1.5411935298621688, + 0.7534486589746342, + 0.0, + 0.0, +] + +Kp = np.array([12000.0, 2000.0, 2000.0, 10, 10, 10]) +Kd = 2 * np.sqrt(Kp) +Kd[3:] = np.asarray([0.00, 0.00, 0.00]) +NULLSPACE_Kp = np.array([1000] * 9) + +if __name__ == "__main__": + + robot = BulletRobot( + urdf_path=get_urdf_from_awesome_robot_descriptions("panda_description"), + default_joint_positions=NEUTRAL_JOINT_POS, + enable_torque_mode=True, # enable to be able to use torque control + ee_names=["panda_hand"], + run_async=False, # set to False to enable stepping simulation manually + ) + + controller = CartesianImpedanceController( + robot=robot, + kp=Kp, + kd=Kd, + null_kp=NULLSPACE_Kp, + nullspace_pos_target=NEUTRAL_JOINT_POS, + ) + + robot.step() + curr_ee_pos, curr_ee_ori = robot.get_link_pose(link_id=robot.ee_ids[0]) + controller.set_target(goal_pos=curr_ee_pos.copy(), goal_ori=curr_ee_ori.copy()) + + while True: + + joint_cmds, _ = controller.compute_cmd() + robot.set_actuated_joint_commands(tau=joint_cmds) + + robot.step() # step simulation + time.sleep(0.01) diff --git a/examples/impedance_controllers.py b/examples/impedance_controllers.py new file mode 100644 index 0000000..f9c4aa4 --- /dev/null +++ b/examples/impedance_controllers.py @@ -0,0 +1,99 @@ +import numpy as np +from pybullet_robot.bullet_robot import BulletRobot + + +# pylint: disable=C0116 +def quat2rpy(quat: np.ndarray) -> tuple: + q1, q2, q3, q0 = quat + roll = np.arctan2( + 2 * ((q2 * q3) + (q0 * q1)), q0**2 - q1**2 - q2**2 + q3**2 + ) # radians + pitch = np.arcsin(2 * ((q1 * q3) - (q0 * q2))) + yaw = np.arctan2(2 * ((q1 * q2) + (q0 * q3)), q0**2 + q1**2 - q2**2 - q3**2) + return np.array((roll, pitch, yaw)) + + +def wrap_angle(angle: float | np.ndarray) -> float | np.ndarray: + return (angle + np.pi) % (2 * np.pi) - np.pi + + +class CartesianImpedanceController: + """Simplified PD control for end-effector tracking.""" + + def __init__( + self, + robot: BulletRobot, + kp: np.array, + kd: np.ndarray, + null_kp: np.ndarray, + nullspace_pos_target: np.ndarray, + ): + + self._robot = robot + self._kp = kp + self._kd = kd + self._null_kp = null_kp + self._nullspace_target = nullspace_pos_target + self._goal_pos: np.ndarray = None + self._goal_ori: np.ndarray = None + + def set_target(self, goal_pos: np.ndarray, goal_ori: np.ndarray): + self._goal_pos = goal_pos + self._goal_ori = goal_ori + + def compute_cmd(self): + curr_pos, curr_ori = self._robot.get_link_pose( + link_id=self._robot.get_link_id(link_name=self._robot.ee_names[0]) + ) + curr_joint_pos = self._robot.get_actuated_joint_positions() + delta_pos = self._goal_pos - curr_pos + + delta_ori = wrap_angle( + wrap_angle(quat2rpy(self._goal_ori)) - wrap_angle(quat2rpy(curr_ori)) + ) + + curr_vel, curr_omg = self._robot.get_link_velocity( + link_id=self._robot.get_link_id(link_name=self._robot.ee_names[0]) + ) + print(wrap_angle(quat2rpy(self._goal_ori)), wrap_angle(quat2rpy(curr_ori))) + + cmd_force = np.zeros(6) + cmd_force[:3] = self._kp[:3] * delta_pos - self._kd[:3] * curr_vel + cmd_force[3:] = self._kp[3:] * delta_ori - self._kd[3:] * curr_omg + + error = np.asarray([np.linalg.norm(delta_pos), np.linalg.norm(delta_ori)]) + + jac = self._robot.get_jacobian(ee_link_name=self._robot.ee_names[0]) + null_space_filter = self._null_kp.dot( + np.eye(curr_joint_pos.size) - jac.T.dot(np.linalg.pinv(jac.T, rcond=1e-3)) + ) + tau = jac.T.dot(cmd_force.reshape([-1, 1])) + null_space_filter.dot( + (self._nullspace_target - curr_joint_pos) + ) + # joint torques to be commanded + return tau.flatten(), error + + +class JointImpedanceController: + """Simplified PD control for end-effector tracking.""" + + def __init__(self, robot: BulletRobot, kp: np.array, kd: np.ndarray): + + self._robot = robot + self._kp = kp + self._kd = kd + self._goal_joint_pos: np.ndarray = None + + def set_target(self, goal_joint_pos: np.ndarray): + self._goal_joint_pos = goal_joint_pos + + def compute_cmd(self): + curr_joint_pos = self._robot.get_actuated_joint_positions() + curr_joint_vel = self._robot.get_actuated_joint_velocities() + + delta_pos = self._goal_joint_pos - curr_joint_pos + # Desired joint effort commands computed using PD law + tau = self._kp * delta_pos - self._kd * curr_joint_vel + + # joint torques to be commanded + return tau, np.linalg.norm(delta_pos) diff --git a/pixi.lock b/pixi.lock new file mode 100644 index 0000000..be4187a --- /dev/null +++ b/pixi.lock @@ -0,0 +1,870 @@ +version: 5 +environments: + default: + channels: + - url: https://conda.anaconda.org/conda-forge/ + indexes: + - https://pypi.org/simple + packages: + linux-64: + - conda: https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/linux-64/bullet-cpp-3.25-hfb8ada1_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-h4bc722e_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ca-certificates-2024.7.4-hbcca054_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.40-hf3520f5_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libblas-3.9.0-23_linux64_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.9.0-23_linux64_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.6.2-h59595ed_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.4.2-h7f98852_5.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-14.1.0-h77fa898_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-14.1.0-h69a702a_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-14.1.0-hc5f4f2c_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-14.1.0-h77fa898_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.9.0-23_linux64_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hd590300_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.27-pthreads_hac2b453_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.46.0-hde9e2c9_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-14.1.0-hc0a3c3a_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.38.1-h0b41bf4_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.16-hd590300_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-h4ab18f5_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h59595ed_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/numpy-1.26.4-py312heda63a1_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.3.1-h4bc722e_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-h36c2ea0_1001.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/linux-64/pybullet-3.25-py312hfb8ada1_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.12.4-h194c7f8_0_cpython.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/python_abi-3.12-4_cp312.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8228510_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/scipy-1.14.0-py312hc2bc53b_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h4845f30_101.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2024a-h0c530f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-kbproto-1.0.7-h7f98852_1002.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.9-hb711507_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.11-hd590300_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.3-h7f98852_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.4-h0b41bf4_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-xextproto-7.3.0-h0b41bf4_1003.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-xproto-7.0.31-h7f98852_1007.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/linux-64/xz-5.2.6-h166bdaf_0.tar.bz2 + - pypi: https://files.pythonhosted.org/packages/fd/5b/8f0c4a5bb9fd491c277c21eff7ccae71b47d43c4446c9d0c6cff2fe8c2c4/gitdb-4.0.11-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e9/bd/cc3a402a6439c15c3d4294333e13042b915bbeab54edc457c723931fed3f/GitPython-3.1.43-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/f3/94/5ce4c471f79a516492dda65d81e1864cdc1378eebd0e7ae0bdc871a12e91/robot_descriptions-1.11.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/a7/a5/10f97f73544edcdef54409f1d839f6049a0d79df68adbc1ceb24d1aaca42/smmap-5.0.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/48/5d/acf5905c36149bbaec41ccf7f2b68814647347b72075ac0b1fe3022fdc73/tqdm-4.66.5-py3-none-any.whl + - pypi: . +packages: +- kind: conda + name: _libgcc_mutex + version: '0.1' + build: conda_forge + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 + sha256: fe51de6107f9edc7aa4f786a70f4a883943bc9d39b3bb7307c04c41410990726 + md5: d7c89558ba9fa0495403155b64376d81 + license: None + purls: [] + size: 2562 + timestamp: 1578324546067 +- kind: conda + name: _openmp_mutex + version: '4.5' + build: 2_gnu + build_number: 16 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2 + sha256: fbe2c5e56a653bebb982eda4876a9178aedfc2b545f25d0ce9c4c0b508253d22 + md5: 73aaf86a425cc6e73fcf236a5a46396d + depends: + - _libgcc_mutex 0.1 conda_forge + - libgomp >=7.5.0 + constrains: + - openmp_impl 9999 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 23621 + timestamp: 1650670423406 +- kind: conda + name: bullet-cpp + version: '3.25' + build: hfb8ada1_2 + build_number: 2 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/bullet-cpp-3.25-hfb8ada1_2.conda + sha256: f806db7366beaf8f5104296eb05db43ca5995d2af2ebd61233d374177591e617 + md5: 612465ad2322dbd5e73d0de9077bfaa7 + depends: + - libgcc-ng >=12 + - libstdcxx-ng >=12 + - numpy >=1.26.0,<2.0a0 + - python_abi 3.12.* *_cp312 + - xorg-libx11 >=1.8.7,<2.0a0 + - xorg-libxext >=1.3.4,<2.0a0 + license: Zlib + purls: [] + size: 42326669 + timestamp: 1697298022245 +- kind: conda + name: bzip2 + version: 1.0.8 + build: h4bc722e_7 + build_number: 7 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-h4bc722e_7.conda + sha256: 5ced96500d945fb286c9c838e54fa759aa04a7129c59800f0846b4335cee770d + md5: 62ee74e96c5ebb0af99386de58cf9553 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc-ng >=12 + license: bzip2-1.0.6 + license_family: BSD + purls: [] + size: 252783 + timestamp: 1720974456583 +- kind: conda + name: ca-certificates + version: 2024.7.4 + build: hbcca054_0 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/ca-certificates-2024.7.4-hbcca054_0.conda + sha256: c1548a3235376f464f9931850b64b02492f379b2f2bb98bc786055329b080446 + md5: 23ab7665c5f63cfb9f1f6195256daac6 + license: ISC + purls: [] + size: 154853 + timestamp: 1720077432978 +- kind: pypi + name: gitdb + version: 4.0.11 + url: https://files.pythonhosted.org/packages/fd/5b/8f0c4a5bb9fd491c277c21eff7ccae71b47d43c4446c9d0c6cff2fe8c2c4/gitdb-4.0.11-py3-none-any.whl + sha256: 81a3407ddd2ee8df444cbacea00e2d038e40150acfa3001696fe0dcf1d3adfa4 + requires_dist: + - smmap<6,>=3.0.1 + requires_python: '>=3.7' +- kind: pypi + name: gitpython + version: 3.1.43 + url: https://files.pythonhosted.org/packages/e9/bd/cc3a402a6439c15c3d4294333e13042b915bbeab54edc457c723931fed3f/GitPython-3.1.43-py3-none-any.whl + sha256: eec7ec56b92aad751f9912a73404bc02ba212a23adb2c7098ee668417051a1ff + requires_dist: + - gitdb<5,>=4.0.1 + - typing-extensions>=3.7.4.3 ; python_version < '3.8' + - sphinx==4.3.2 ; extra == 'doc' + - sphinx-rtd-theme ; extra == 'doc' + - sphinxcontrib-applehelp<=1.0.4,>=1.0.2 ; extra == 'doc' + - sphinxcontrib-devhelp==1.0.2 ; extra == 'doc' + - sphinxcontrib-htmlhelp<=2.0.1,>=2.0.0 ; extra == 'doc' + - sphinxcontrib-qthelp==1.0.3 ; extra == 'doc' + - sphinxcontrib-serializinghtml==1.1.5 ; extra == 'doc' + - sphinx-autodoc-typehints ; extra == 'doc' + - coverage[toml] ; extra == 'test' + - ddt!=1.4.3,>=1.1.1 ; extra == 'test' + - mypy ; extra == 'test' + - pre-commit ; extra == 'test' + - pytest>=7.3.1 ; extra == 'test' + - pytest-cov ; extra == 'test' + - pytest-instafail ; extra == 'test' + - pytest-mock ; extra == 'test' + - pytest-sugar ; extra == 'test' + - typing-extensions ; python_version < '3.11' and extra == 'test' + - mock ; python_version < '3.8' and extra == 'test' + requires_python: '>=3.7' +- kind: conda + name: ld_impl_linux-64 + version: '2.40' + build: hf3520f5_7 + build_number: 7 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.40-hf3520f5_7.conda + sha256: 764b6950aceaaad0c67ef925417594dd14cd2e22fff864aeef455ac259263d15 + md5: b80f2f396ca2c28b8c14c437a4ed1e74 + constrains: + - binutils_impl_linux-64 2.40 + license: GPL-3.0-only + license_family: GPL + purls: [] + size: 707602 + timestamp: 1718625640445 +- kind: conda + name: libblas + version: 3.9.0 + build: 23_linux64_openblas + build_number: 23 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/libblas-3.9.0-23_linux64_openblas.conda + sha256: edb1cee5da3ac4936940052dcab6969673ba3874564f90f5110f8c11eed789c2 + md5: 96c8450a40aa2b9733073a9460de972c + depends: + - libopenblas >=0.3.27,<0.3.28.0a0 + - libopenblas >=0.3.27,<1.0a0 + constrains: + - liblapacke 3.9.0 23_linux64_openblas + - libcblas 3.9.0 23_linux64_openblas + - liblapack 3.9.0 23_linux64_openblas + - blas * openblas + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 14880 + timestamp: 1721688759937 +- kind: conda + name: libcblas + version: 3.9.0 + build: 23_linux64_openblas + build_number: 23 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.9.0-23_linux64_openblas.conda + sha256: 3e7a3236e7e03e308e1667d91d0aa70edd0cba96b4b5563ef4adde088e0881a5 + md5: eede29b40efa878cbe5bdcb767e97310 + depends: + - libblas 3.9.0 23_linux64_openblas + constrains: + - liblapacke 3.9.0 23_linux64_openblas + - liblapack 3.9.0 23_linux64_openblas + - blas * openblas + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 14798 + timestamp: 1721688767584 +- kind: conda + name: libexpat + version: 2.6.2 + build: h59595ed_0 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.6.2-h59595ed_0.conda + sha256: 331bb7c7c05025343ebd79f86ae612b9e1e74d2687b8f3179faec234f986ce19 + md5: e7ba12deb7020dd080c6c70e7b6f6a3d + depends: + - libgcc-ng >=12 + constrains: + - expat 2.6.2.* + license: MIT + license_family: MIT + purls: [] + size: 73730 + timestamp: 1710362120304 +- kind: conda + name: libffi + version: 3.4.2 + build: h7f98852_5 + build_number: 5 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.4.2-h7f98852_5.tar.bz2 + sha256: ab6e9856c21709b7b517e940ae7028ae0737546122f83c2aa5d692860c3b149e + md5: d645c6d2ac96843a2bfaccd2d62b3ac3 + depends: + - libgcc-ng >=9.4.0 + license: MIT + license_family: MIT + purls: [] + size: 58292 + timestamp: 1636488182923 +- kind: conda + name: libgcc-ng + version: 14.1.0 + build: h77fa898_0 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-14.1.0-h77fa898_0.conda + sha256: b8e869ac96591cda2704bf7e77a301025e405227791a0bddf14a3dac65125538 + md5: ca0fad6a41ddaef54a153b78eccb5037 + depends: + - _libgcc_mutex 0.1 conda_forge + - _openmp_mutex >=4.5 + constrains: + - libgomp 14.1.0 h77fa898_0 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + purls: [] + size: 842109 + timestamp: 1719538896937 +- kind: conda + name: libgfortran-ng + version: 14.1.0 + build: h69a702a_0 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-14.1.0-h69a702a_0.conda + sha256: ef624dacacf97b2b0af39110b36e2fd3e39e358a1a6b7b21b85c9ac22d8ffed9 + md5: f4ca84fbd6d06b0a052fb2d5b96dde41 + depends: + - libgfortran5 14.1.0 hc5f4f2c_0 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + purls: [] + size: 49893 + timestamp: 1719538933879 +- kind: conda + name: libgfortran5 + version: 14.1.0 + build: hc5f4f2c_0 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-14.1.0-hc5f4f2c_0.conda + sha256: a67d66b1e60a8a9a9e4440cee627c959acb4810cb182e089a4b0729bfdfbdf90 + md5: 6456c2620c990cd8dde2428a27ba0bc5 + depends: + - libgcc-ng >=14.1.0 + constrains: + - libgfortran-ng 14.1.0 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + purls: [] + size: 1457561 + timestamp: 1719538909168 +- kind: conda + name: libgomp + version: 14.1.0 + build: h77fa898_0 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/libgomp-14.1.0-h77fa898_0.conda + sha256: 7699df61a1f6c644b3576a40f54791561f2845983120477a16116b951c9cdb05 + md5: ae061a5ed5f05818acdf9adab72c146d + depends: + - _libgcc_mutex 0.1 conda_forge + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + purls: [] + size: 456925 + timestamp: 1719538796073 +- kind: conda + name: liblapack + version: 3.9.0 + build: 23_linux64_openblas + build_number: 23 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.9.0-23_linux64_openblas.conda + sha256: 25c7aef86c8a1d9db0e8ee61aa7462ba3b46b482027a65d66eb83e3e6f949043 + md5: 2af0879961951987e464722fd00ec1e0 + depends: + - libblas 3.9.0 23_linux64_openblas + constrains: + - liblapacke 3.9.0 23_linux64_openblas + - libcblas 3.9.0 23_linux64_openblas + - blas * openblas + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 14823 + timestamp: 1721688775172 +- kind: conda + name: libnsl + version: 2.0.1 + build: hd590300_0 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hd590300_0.conda + sha256: 26d77a3bb4dceeedc2a41bd688564fe71bf2d149fdcf117049970bc02ff1add6 + md5: 30fd6e37fe21f86f4bd26d6ee73eeec7 + depends: + - libgcc-ng >=12 + license: LGPL-2.1-only + license_family: GPL + purls: [] + size: 33408 + timestamp: 1697359010159 +- kind: conda + name: libopenblas + version: 0.3.27 + build: pthreads_hac2b453_1 + build_number: 1 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.27-pthreads_hac2b453_1.conda + sha256: 714cb82d7c4620ea2635a92d3df263ab841676c9b183d0c01992767bb2451c39 + md5: ae05ece66d3924ac3d48b4aa3fa96cec + depends: + - libgcc-ng >=12 + - libgfortran-ng + - libgfortran5 >=12.3.0 + constrains: + - openblas >=0.3.27,<0.3.28.0a0 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 5563053 + timestamp: 1720426334043 +- kind: conda + name: libsqlite + version: 3.46.0 + build: hde9e2c9_0 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.46.0-hde9e2c9_0.conda + sha256: daee3f68786231dad457d0dfde3f7f1f9a7f2018adabdbb864226775101341a8 + md5: 18aa975d2094c34aef978060ae7da7d8 + depends: + - libgcc-ng >=12 + - libzlib >=1.2.13,<2.0a0 + license: Unlicense + purls: [] + size: 865346 + timestamp: 1718050628718 +- kind: conda + name: libstdcxx-ng + version: 14.1.0 + build: hc0a3c3a_0 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-14.1.0-hc0a3c3a_0.conda + sha256: 88c42b388202ffe16adaa337e36cf5022c63cf09b0405cf06fc6aeacccbe6146 + md5: 1cb187a157136398ddbaae90713e2498 + depends: + - libgcc-ng 14.1.0 h77fa898_0 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + purls: [] + size: 3881307 + timestamp: 1719538923443 +- kind: conda + name: libuuid + version: 2.38.1 + build: h0b41bf4_0 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.38.1-h0b41bf4_0.conda + sha256: 787eb542f055a2b3de553614b25f09eefb0a0931b0c87dbcce6efdfd92f04f18 + md5: 40b61aab5c7ba9ff276c41cfffe6b80b + depends: + - libgcc-ng >=12 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 33601 + timestamp: 1680112270483 +- kind: conda + name: libxcb + version: '1.16' + build: hd590300_0 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.16-hd590300_0.conda + sha256: 7180375f37fd264bb50672a63da94536d4abd81ccec059e932728ae056324b3a + md5: 151cba22b85a989c2d6ef9633ffee1e4 + depends: + - libgcc-ng >=12 + - pthread-stubs + - xorg-libxau >=1.0.11,<2.0a0 + - xorg-libxdmcp + license: MIT + license_family: MIT + purls: [] + size: 394932 + timestamp: 1693088990429 +- kind: conda + name: libxcrypt + version: 4.4.36 + build: hd590300_1 + build_number: 1 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/libxcrypt-4.4.36-hd590300_1.conda + sha256: 6ae68e0b86423ef188196fff6207ed0c8195dd84273cb5623b85aa08033a410c + md5: 5aa797f8787fe7a17d1b0821485b5adc + depends: + - libgcc-ng >=12 + license: LGPL-2.1-or-later + purls: [] + size: 100393 + timestamp: 1702724383534 +- kind: conda + name: libzlib + version: 1.3.1 + build: h4ab18f5_1 + build_number: 1 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-h4ab18f5_1.conda + sha256: adf6096f98b537a11ae3729eaa642b0811478f0ea0402ca67b5108fe2cb0010d + md5: 57d7dc60e9325e3de37ff8dffd18e814 + depends: + - libgcc-ng >=12 + constrains: + - zlib 1.3.1 *_1 + license: Zlib + license_family: Other + purls: [] + size: 61574 + timestamp: 1716874187109 +- kind: conda + name: ncurses + version: '6.5' + build: h59595ed_0 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h59595ed_0.conda + sha256: 4fc3b384f4072b68853a0013ea83bdfd3d66b0126e2238e1d6e1560747aa7586 + md5: fcea371545eda051b6deafb24889fc69 + depends: + - libgcc-ng >=12 + license: X11 AND BSD-3-Clause + purls: [] + size: 887465 + timestamp: 1715194722503 +- kind: conda + name: numpy + version: 1.26.4 + build: py312heda63a1_0 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/numpy-1.26.4-py312heda63a1_0.conda + sha256: fe3459c75cf84dcef6ef14efcc4adb0ade66038ddd27cadb894f34f4797687d8 + md5: d8285bea2a350f63fab23bf460221f3f + depends: + - libblas >=3.9.0,<4.0a0 + - libcblas >=3.9.0,<4.0a0 + - libgcc-ng >=12 + - liblapack >=3.9.0,<4.0a0 + - libstdcxx-ng >=12 + - python >=3.12,<3.13.0a0 + - python_abi 3.12.* *_cp312 + constrains: + - numpy-base <0a0 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/numpy?source=conda-forge-mapping + size: 7484186 + timestamp: 1707225809722 +- kind: conda + name: openssl + version: 3.3.1 + build: h4bc722e_2 + build_number: 2 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.3.1-h4bc722e_2.conda + sha256: b294b3cc706ad1048cdb514f0db3da9f37ae3fcc0c53a7104083dd0918adb200 + md5: e1b454497f9f7c1147fdde4b53f1b512 + depends: + - __glibc >=2.17,<3.0.a0 + - ca-certificates + - libgcc-ng >=12 + constrains: + - pyopenssl >=22.1 + license: Apache-2.0 + license_family: Apache + purls: [] + size: 2895213 + timestamp: 1721194688955 +- kind: conda + name: pthread-stubs + version: '0.4' + build: h36c2ea0_1001 + build_number: 1001 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-h36c2ea0_1001.tar.bz2 + sha256: 67c84822f87b641d89df09758da498b2d4558d47b920fd1d3fe6d3a871e000ff + md5: 22dad4df6e8630e8dff2428f6f6a7036 + depends: + - libgcc-ng >=7.5.0 + license: MIT + license_family: MIT + purls: [] + size: 5625 + timestamp: 1606147468727 +- kind: conda + name: pybullet + version: '3.25' + build: py312hfb8ada1_2 + build_number: 2 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/pybullet-3.25-py312hfb8ada1_2.conda + sha256: 65746a57c164e6ac3cbf21c0bef2e055f257affb00da75bb99b433980f9395c5 + md5: b74ae047db52b9092976ac255654cc46 + depends: + - bullet-cpp 3.25 hfb8ada1_2 + - libgcc-ng >=12 + - libstdcxx-ng >=12 + - numpy >=1.26.0,<2.0a0 + - python >=3.12,<3.13.0a0 + - python_abi 3.12.* *_cp312 + license: Zlib + purls: + - pkg:pypi/pybullet?source=conda-forge-mapping + size: 62942254 + timestamp: 1697298309816 +- kind: pypi + name: pybullet-robot + version: 0.1.1 + path: . + sha256: 073f3e0406278a335223ae9319c75d539c79927da7ab0af034f38aa9ced42007 + requires_dist: + - robot-descriptions>=1.11.0,<2 + requires_python: '>=3.10' + editable: true +- kind: conda + name: python + version: 3.12.4 + build: h194c7f8_0_cpython + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/python-3.12.4-h194c7f8_0_cpython.conda + sha256: 97a78631e6c928bf7ad78d52f7f070fcf3bd37619fa48dc4394c21cf3058cdee + md5: d73490214f536cccb5819e9873048c92 + depends: + - bzip2 >=1.0.8,<2.0a0 + - ld_impl_linux-64 >=2.36.1 + - libexpat >=2.6.2,<3.0a0 + - libffi >=3.4,<4.0a0 + - libgcc-ng >=12 + - libnsl >=2.0.1,<2.1.0a0 + - libsqlite >=3.46.0,<4.0a0 + - libuuid >=2.38.1,<3.0a0 + - libxcrypt >=4.4.36 + - libzlib >=1.3.1,<2.0a0 + - ncurses >=6.5,<7.0a0 + - openssl >=3.3.1,<4.0a0 + - readline >=8.2,<9.0a0 + - tk >=8.6.13,<8.7.0a0 + - tzdata + - xz >=5.2.6,<6.0a0 + constrains: + - python_abi 3.12.* *_cp312 + license: Python-2.0 + purls: [] + size: 32073625 + timestamp: 1718621771849 +- kind: conda + name: python_abi + version: '3.12' + build: 4_cp312 + build_number: 4 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/python_abi-3.12-4_cp312.conda + sha256: 182a329de10a4165f6e8a3804caf751f918f6ea6176dd4e5abcdae1ed3095bf6 + md5: dccc2d142812964fcc6abdc97b672dff + constrains: + - python 3.12.* *_cpython + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 6385 + timestamp: 1695147396604 +- kind: conda + name: readline + version: '8.2' + build: h8228510_1 + build_number: 1 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8228510_1.conda + sha256: 5435cf39d039387fbdc977b0a762357ea909a7694d9528ab40f005e9208744d7 + md5: 47d31b792659ce70f470b5c82fdfb7a4 + depends: + - libgcc-ng >=12 + - ncurses >=6.3,<7.0a0 + license: GPL-3.0-only + license_family: GPL + purls: [] + size: 281456 + timestamp: 1679532220005 +- kind: pypi + name: robot-descriptions + version: 1.11.0 + url: https://files.pythonhosted.org/packages/f3/94/5ce4c471f79a516492dda65d81e1864cdc1378eebd0e7ae0bdc871a12e91/robot_descriptions-1.11.0-py3-none-any.whl + sha256: 2c6e833ab35204f68a533d2cebb60692c1acbb8468b5f8292af0494b17621324 + requires_dist: + - gitpython>=3.1.18 + - tqdm>=4.64.0 + - pin>=2.6.10 ; extra == 'opts' + - idyntree>=8.0.0 ; extra == 'opts' + - robomeshcat>=1.0.4 ; extra == 'opts' + - yourdfpy>=0.0.56 ; extra == 'opts' + requires_python: '>=3.7' +- kind: conda + name: scipy + version: 1.14.0 + build: py312hc2bc53b_1 + build_number: 1 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/scipy-1.14.0-py312hc2bc53b_1.conda + sha256: 6bd24bc823863bb568ffe0ebdfb506d4413d94d15b478b12a0b223d9373f531e + md5: eae80145f63aa04a02dda456d4883b46 + depends: + - libblas >=3.9.0,<4.0a0 + - libcblas >=3.9.0,<4.0a0 + - libgcc-ng >=12 + - libgfortran-ng + - libgfortran5 >=12.3.0 + - liblapack >=3.9.0,<4.0a0 + - libstdcxx-ng >=12 + - numpy <2.3 + - numpy >=1.19,<3 + - python >=3.12,<3.13.0a0 + - python_abi 3.12.* *_cp312 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/scipy?source=conda-forge-mapping + size: 17653680 + timestamp: 1720324049729 +- kind: pypi + name: smmap + version: 5.0.1 + url: https://files.pythonhosted.org/packages/a7/a5/10f97f73544edcdef54409f1d839f6049a0d79df68adbc1ceb24d1aaca42/smmap-5.0.1-py3-none-any.whl + sha256: e6d8668fa5f93e706934a62d7b4db19c8d9eb8cf2adbb75ef1b675aa332b69da + requires_python: '>=3.7' +- kind: conda + name: tk + version: 8.6.13 + build: noxft_h4845f30_101 + build_number: 101 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h4845f30_101.conda + sha256: e0569c9caa68bf476bead1bed3d79650bb080b532c64a4af7d8ca286c08dea4e + md5: d453b98d9c83e71da0741bb0ff4d76bc + depends: + - libgcc-ng >=12 + - libzlib >=1.2.13,<2.0.0a0 + license: TCL + license_family: BSD + purls: [] + size: 3318875 + timestamp: 1699202167581 +- kind: pypi + name: tqdm + version: 4.66.5 + url: https://files.pythonhosted.org/packages/48/5d/acf5905c36149bbaec41ccf7f2b68814647347b72075ac0b1fe3022fdc73/tqdm-4.66.5-py3-none-any.whl + sha256: 90279a3770753eafc9194a0364852159802111925aa30eb3f9d85b0e805ac7cd + requires_dist: + - colorama ; platform_system == 'Windows' + - pytest>=6 ; extra == 'dev' + - pytest-cov ; extra == 'dev' + - pytest-timeout ; extra == 'dev' + - pytest-xdist ; extra == 'dev' + - ipywidgets>=6 ; extra == 'notebook' + - slack-sdk ; extra == 'slack' + - requests ; extra == 'telegram' + requires_python: '>=3.7' +- kind: conda + name: tzdata + version: 2024a + build: h0c530f3_0 + subdir: noarch + noarch: generic + url: https://conda.anaconda.org/conda-forge/noarch/tzdata-2024a-h0c530f3_0.conda + sha256: 7b2b69c54ec62a243eb6fba2391b5e443421608c3ae5dbff938ad33ca8db5122 + md5: 161081fc7cec0bfda0d86d7cb595f8d8 + license: LicenseRef-Public-Domain + purls: [] + size: 119815 + timestamp: 1706886945727 +- kind: conda + name: xorg-kbproto + version: 1.0.7 + build: h7f98852_1002 + build_number: 1002 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/xorg-kbproto-1.0.7-h7f98852_1002.tar.bz2 + sha256: e90b0a6a5d41776f11add74aa030f789faf4efd3875c31964d6f9cfa63a10dd1 + md5: 4b230e8381279d76131116660f5a241a + depends: + - libgcc-ng >=9.3.0 + license: MIT + license_family: MIT + purls: [] + size: 27338 + timestamp: 1610027759842 +- kind: conda + name: xorg-libx11 + version: 1.8.9 + build: hb711507_1 + build_number: 1 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.9-hb711507_1.conda + sha256: 66eabe62b66c1597c4a755dcd3f4ce2c78adaf7b32e25dfee45504d67d7735c1 + md5: 4a6d410296d7e39f00bacdee7df046e9 + depends: + - libgcc-ng >=12 + - libxcb >=1.16,<1.17.0a0 + - xorg-kbproto + - xorg-xextproto >=7.3.0,<8.0a0 + - xorg-xproto + license: MIT + license_family: MIT + purls: [] + size: 832198 + timestamp: 1718846846409 +- kind: conda + name: xorg-libxau + version: 1.0.11 + build: hd590300_0 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.11-hd590300_0.conda + sha256: 309751371d525ce50af7c87811b435c176915239fc9e132b99a25d5e1703f2d4 + md5: 2c80dc38fface310c9bd81b17037fee5 + depends: + - libgcc-ng >=12 + license: MIT + license_family: MIT + purls: [] + size: 14468 + timestamp: 1684637984591 +- kind: conda + name: xorg-libxdmcp + version: 1.1.3 + build: h7f98852_0 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.3-h7f98852_0.tar.bz2 + sha256: 4df7c5ee11b8686d3453e7f3f4aa20ceef441262b49860733066c52cfd0e4a77 + md5: be93aabceefa2fac576e971aef407908 + depends: + - libgcc-ng >=9.3.0 + license: MIT + license_family: MIT + purls: [] + size: 19126 + timestamp: 1610071769228 +- kind: conda + name: xorg-libxext + version: 1.3.4 + build: h0b41bf4_2 + build_number: 2 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.4-h0b41bf4_2.conda + sha256: 73e5cfbdff41ef8a844441f884412aa5a585a0f0632ec901da035a03e1fe1249 + md5: 82b6df12252e6f32402b96dacc656fec + depends: + - libgcc-ng >=12 + - xorg-libx11 >=1.7.2,<2.0a0 + - xorg-xextproto + license: MIT + license_family: MIT + purls: [] + size: 50143 + timestamp: 1677036907815 +- kind: conda + name: xorg-xextproto + version: 7.3.0 + build: h0b41bf4_1003 + build_number: 1003 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/xorg-xextproto-7.3.0-h0b41bf4_1003.conda + sha256: b8dda3b560e8a7830fe23be1c58cc41f407b2e20ae2f3b6901eb5842ba62b743 + md5: bce9f945da8ad2ae9b1d7165a64d0f87 + depends: + - libgcc-ng >=12 + license: MIT + license_family: MIT + purls: [] + size: 30270 + timestamp: 1677036833037 +- kind: conda + name: xorg-xproto + version: 7.0.31 + build: h7f98852_1007 + build_number: 1007 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/xorg-xproto-7.0.31-h7f98852_1007.tar.bz2 + sha256: f197bb742a17c78234c24605ad1fe2d88b1d25f332b75d73e5ba8cf8fbc2a10d + md5: b4a4381d54784606820704f7b5f05a15 + depends: + - libgcc-ng >=9.3.0 + license: MIT + license_family: MIT + purls: [] + size: 74922 + timestamp: 1607291557628 +- kind: conda + name: xz + version: 5.2.6 + build: h166bdaf_0 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/xz-5.2.6-h166bdaf_0.tar.bz2 + sha256: 03a6d28ded42af8a347345f82f3eebdd6807a08526d47899a42d62d319609162 + md5: 2161070d867d1b1204ea749c8eec4ef0 + depends: + - libgcc-ng >=12 + license: LGPL-2.1 and GPL-2.0 + purls: [] + size: 418368 + timestamp: 1660346797927 diff --git a/pyproject.toml b/pyproject.toml index 22303bf..d1693a2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,25 +1,24 @@ -[tool.poetry] -name = "pybullet-robot" +[project] +name = "pybullet_robot" version = "0.1.1" -description = "" -authors = ["JustaGist "] -readme = "README.md" +description = "A generel Python interface class for robot simulations using PyBullet. Also provides an IK interface for multi-end-effector robots that uses bullet physics as a solver." +authors = [{ name = "Saif Sidhik", email = "mail@saifsidhik.page" }] +requires-python = ">= 3.10" +dependencies = ["robot-descriptions>=1.11.0,<2"] -[tool.poetry.dependencies] -python = ">=3.10" -pybullet = ">3.1" -robot-descriptions = ">=1.10.0" -numpy = "*" -scipy = "^1.13.0" +[build-system] +requires = ["setuptools"] +build-backend = "setuptools.build_meta" -[tool.poetry.group.docs] -optional = true +[tool.pixi.project] +channels = ["conda-forge"] +platforms = ["linux-64"] -[tool.poetry.group.docs.dependencies] -sphinxcontrib-napoleon = "*" -sphinx-rtd-theme = "*" -sphinx-autoapi = "*" +[tool.pixi.pypi-dependencies] +pybullet_robot = { path = ".", editable = true } -[build-system] -requires = ["poetry-core"] -build-backend = "poetry.core.masonry.api" +[tool.pixi.dependencies] +python = ">=3.10" +pybullet = ">=3.25,<4" +numpy = ">=1.26.4,<2" +scipy = ">=1.14.0,<2"