diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 3bdc7f9..1b129c9 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -15,7 +15,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - libfranka-version: ["0.7.1", "0.8.0", "0.9.2", "0.13.3"] + libfranka-version: ["0.7.1", "0.8.0", "0.9.2", "0.12.1", "0.13.6", "0.14.2", "0.15.0"] steps: - uses: actions/checkout@v3 - uses: actions/setup-python@v3 @@ -39,11 +39,11 @@ jobs: - name: Build documentation run: cd docs && make html - name: Setup Pages - uses: actions/configure-pages@v3 + uses: actions/configure-pages@v5 - name: Upload artifact - uses: actions/upload-pages-artifact@v2 + uses: actions/upload-pages-artifact@v3 with: path: ./docs/_build/html - name: Deploy to GitHub Pages id: deployment - uses: actions/deploy-pages@v2 + uses: actions/deploy-pages@v4 diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index f7805ae..184ffa3 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -9,7 +9,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - libfranka-version: ["0.7.1", "0.8.0", "0.9.2", "0.13.3"] + libfranka-version: ["0.7.1", "0.8.0", "0.9.2", "0.12.1", "0.13.6", "0.14.2", "0.15.0"] steps: - uses: actions/checkout@v3 - uses: actions/setup-python@v3 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c7c1b6f..110ba88 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -5,7 +5,7 @@ on: types: [published] env: - VERSION: 0.8.1 + VERSION: 1.0.0 permissions: write-all @@ -15,7 +15,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - libfranka-version: ["0.7.1", "0.8.0", "0.9.2", "0.13.3"] + libfranka-version: ["0.7.1", "0.8.0", "0.9.2", "0.12.1", "0.13.6", "0.14.2", "0.15.0"] steps: - uses: actions/checkout@v3 - uses: actions/setup-python@v3 @@ -52,7 +52,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - libfranka-version: ["0.7.1", "0.8.0", "0.9.2", "0.13.3"] + libfranka-version: ["0.7.1", "0.8.0", "0.9.2", "0.12.1", "0.13.6", "0.14.2", "0.15.0"] steps: - uses: actions/download-artifact@v3 with: diff --git a/CMakeLists.txt b/CMakeLists.txt index 836523c..bd2ad1f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,10 +8,10 @@ set (CMAKE_CXX_STANDARD 17) set(CMAKE_BUILD_TYPE "Release") set(THREADS_PREFER_PTHREAD_FLAG ON) -option(VACUUM_GRIPPER OFF) -if (VACUUM_GRIPPER) - add_definitions(-DVACUUM_GRIPPER=${VACUUM_GRIPPER}) +if(NOT DEFINED LIBFRANKA_VER) + message(FATAL_ERROR "LIBFRANKA_VER must be set! (e.g., -DLIBFRANKA_VER=0x000f00)") endif() +add_compile_definitions(LIBFRANKA_VER=${LIBFRANKA_VER}) find_package(Eigen3 REQUIRED) find_package(Threads REQUIRED) @@ -65,7 +65,9 @@ target_link_libraries(libfranka PUBLIC ) target_include_directories(libfranka SYSTEM PUBLIC + include ${Franka_INCLUDE_DIRS} + ${EIGEN3_INCLUDE_DIRS} ) #target_compile_definitions(libfranka diff --git a/README.md b/README.md index ebb3154..81980fe 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -
panda-py Logo
+
panda-py Logo

panda-py

@@ -30,12 +30,22 @@ This will install panda-py and all its requirements. The pip version ships with ## libfranka Version -There are currently two robot models available from Franka Emika: the Franka Emika Robot (FER, formerly known as Panda) and the Franka Research 3 (FR3). Depending on the installed firmware, the FER supports version <0.10 while the FR3 requires version >=0.10. For details, refer to [this](https://frankaemika.github.io/docs/compatibility.html) compatibility matrix. If you need a libfranka version different from the default 0.9.2, download the respective zip archive from the [release page](https://github.com/JeanElsner/panda-py/releases). Extract the archive and install the wheel for your Python version with pip, e.g., run +There are currently two robot models available from Franka Robotics: the Franka Emika Robot (FER, formerly known as Panda) and the Franka Research 3 (FR3). Depending on the installed firmware, the FER supports libfranka version <0.10 while the FR3 requires version >=0.10. For details, refer to [this](https://frankaemika.github.io/docs/compatibility.html) compatibility matrix. If you need a libfranka version different from the default 0.9.2, download the respective zip archive from the table below. Extract the archive and install the wheel for your Python version with pip, e.g., run ``` pip install panda_python-*libfranka.0.7.1-cp310*.whl ``` to install the binary wheel for libfranka 0.7.1 and Python 3.10. +| Robot System Version | libfranka Version of panda-py | +| ---- | ---- | +| >= 5.7.2 | [panda_py_1.0.0_libfranka_0.15.0.zip](https://github.com/JeanElsner/panda-py/releases/download/v1.0.0/panda_py_1.0.0_libfranka_0.15.0.zip) | +| >= 5.7.0 | [panda_py_1.0.0_libfranka_0.14.2.zip](https://github.com/JeanElsner/panda-py/releases/download/v1.0.0/panda_py_1.0.0_libfranka_0.14.2.zip) | +| >= 5.5.0 | [panda_py_1.0.0_libfranka_0.13.6.zip](https://github.com/JeanElsner/panda-py/releases/download/v1.0.0/panda_py_1.0.0_libfranka_0.13.6.zip) | +| >= 5.2.0 | [panda_py_1.0.0_libfranka_0.12.1.zip](https://github.com/JeanElsner/panda-py/releases/download/v1.0.0/panda_py_1.0.0_libfranka_0.12.1.zip) | +| >= 4.2.1 | [panda_py_1.0.0_libfranka_0.9.2.zip](https://github.com/JeanElsner/panda-py/releases/download/v1.0.0/panda_py_1.0.0_libfranka_0.9.2.zip) | +| >= 4.0.0 | [panda_py_1.0.0_libfranka_0.8.0.zip](https://github.com/JeanElsner/panda-py/releases/download/v1.0.0/panda_py_1.0.0_libfranka_0.8.0.zip) | +| >= 3.0.0 | [panda_py_1.0.0_libfranka_0.7.1.zip](https://github.com/JeanElsner/panda-py/releases/download/v1.0.0/panda_py_1.0.0_libfranka_0.7.1.zip) | + # Citation If you use panda-py in published research, please consider citing the [original software paper](https://www.sciencedirect.com/science/article/pii/S2352711023002285). diff --git a/bin/before_install_centos.sh b/bin/before_install_centos.sh index 33b83ab..849c47d 100755 --- a/bin/before_install_centos.sh +++ b/bin/before_install_centos.sh @@ -1,16 +1,60 @@ #! /bin/bash -sed -i 's/enabled=1/enabled=0/g' /etc/yum/pluginconf.d/fastestmirror.conf -sed -i 's/^mirrorlist/#mirrorlist/g' /etc/yum.repos.d/*.repo -sed -i 's;^.*baseurl=http://mirror;baseurl=https://vault;g' /etc/yum.repos.d/*.repo -fixup-mirrors -yum -y update -fixup-mirrors - -yum install -y openssl-devel +yum install -y eigen3-devel boost-devel openssl-devel + +# Function to compare version numbers (returns true if first version >= second version) +version_ge() { + test "$(printf '%s\n' "$@" | sort -rV | head -n 1)" == "$1"; +} + +# Only install these dependencies for libfranka versions >= 0.14.0 +if version_ge "$LIBFRANKA_VER" "0.14.0"; then + git clone --branch 11.2.0 https://github.com/fmtlib/fmt.git + cd fmt && mkdir fmt && cd fmt + cmake -DCMAKE_POSITION_INDEPENDENT_CODE=TRUE .. + make + make install + cd ../.. + + git clone --branch 1.0.5 https://github.com/ros/urdfdom_headers.git + cd urdfdom_headers && mkdir build && cd build + cmake .. -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_LIBDIR=/usr/lib -DCMAKE_POLICY_VERSION_MINIMUM=3.5 + make + make install + cd ../.. + + git clone --branch 10.0.0 https://github.com/leethomason/tinyxml2.git + cd tinyxml2 && mkdir build && cd build + cmake .. -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_LIBDIR=/usr/lib -DCMAKE_POSITION_INDEPENDENT_CODE=ON + make + make install + cd ../.. + + git clone --branch 1.0.2 https://github.com/ros/console_bridge.git + cd console_bridge && mkdir build && cd build + cmake .. -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_LIBDIR=/usr/lib -DCMAKE_POLICY_VERSION_MINIMUM=3.5 + make + make install + cd ../.. + + git clone --branch 4.0.0 https://github.com/ros/urdfdom.git + cd urdfdom && mkdir build && cd build + cmake .. -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_LIBDIR=/usr/lib + make + make install + cd ../.. + + git clone --recursive --branch v2.7.0 https://github.com/stack-of-tasks/pinocchio.git + cd pinocchio && mkdir build && cd build + cmake .. -DBUILD_TESTING=OFF -DBUILD_PYTHON_INTERFACE=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_INSTALL_LIBDIR=/usr/lib + make -j4 + make install + cd ../.. +fi + git clone https://github.com/pocoproject/poco.git cd poco -git checkout poco-1.9.2-release # focal, jammy uses 1.11.0 +git checkout poco-1.11.0-release mkdir cmake-build cd cmake-build cmake \ @@ -41,12 +85,11 @@ if [[ "$LIBFRANKA_VER" == "0.7.1" || "$LIBFRANKA_VER" == "0.8.0" ]]; then repo="https://github.com/JeanElsner/libfranka.git" fi -yum install -y eigen3-devel boost-devel git clone --recursive $repo cd libfranka git checkout $LIBFRANKA_VER git submodule update mkdir build && cd build -cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTS=OFF -DBUILD_EXAMPLES=OFF .. +cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTS=OFF -DBUILD_EXAMPLES=OFF -DCMAKE_POLICY_VERSION_MINIMUM=3.5 .. cmake --build . make install diff --git a/bin/build.sh b/bin/build.sh index 2cfd69b..a35b830 100755 --- a/bin/build.sh +++ b/bin/build.sh @@ -29,13 +29,7 @@ echo "Current version is $version" change_version() { local pandapy_version="$version+libfranka-$1" - local libfranka_version="LIBFRANKA_VER=$1" - local vacuum_gripper="ON" - - if [[ "$1" == "0.7.1" ]]; then - vacuum_gripper="OFF" - fi - echo "VACUUM_GRIPPER: $vacuum_gripper" + local version_num=$(echo "$1" | awk -F. '{ printf "0x%02x%02x%02x", $1, $2, $3 }') python <=11.0", "requests", "numpy"] +requires-python = ">=3.9" +dependencies = [ "websockets>=11.0", "requests", "numpy>=2.0",] authors = [ { name = "Jean Elsner", email = "jean.elsner@tum.de" }, ] license = {file = "LICENSE"} readme = "README.md" -keywords = ["python", "real-time", "control", "robot", "franka", "emika"] +keywords = [ "python", "real-time", "control", "robot", "franka", "emika", "panda"] classifiers = [ - "Intended Audience :: Science/Research", - "Intended Audience :: Developers", - "License :: OSI Approved :: Apache Software License", - "Topic :: Scientific/Engineering", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", - "Programming Language :: Python :: 3.12", + "Intended Audience :: Science/Research", + "Intended Audience :: Developers", + "License :: OSI Approved :: Apache Software License", + "Topic :: Scientific/Engineering", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] [project.optional-dependencies] -examples = [ - "roboticstoolbox-python", - "matplotlib", - "spatialmath-python", - "ansitable", +examples = [ + "roboticstoolbox-python", + "matplotlib", + "spatialmath-python", + "ansitable", "qpsolvers", ] -docs = [ - "furo", - "sphinx-reredirects", +docs = [ + "furo", + "sphinx-reredirects", "sphinx", ] -dev = [ - "pybind11-stubgen", -] +dev = [ "pybind11-stubgen",] [project.scripts] panda-lock = "panda_py.cli:lock" @@ -53,7 +49,7 @@ panda-release-control = "panda_py.cli:release_control" [tool.cibuildwheel] manylinux-x86_64-image = "manylinux2014" -build = [ "cp37-*", "cp38-*", "cp39-*", "cp310-*", "cp311-*", "cp312-*",] +build = [ "cp39-*", "cp310-*", "cp311-*", "cp312-*",] skip = [ "pp*", "*musllinux*",] environment = "LIBFRANKA_VER=0.9.2" @@ -65,7 +61,7 @@ archs = [ "x86_64",] build-type = "Release" [tool.scikit-build.wheel] -packages = ["src/panda_py"] +packages = [ "src/panda_py",] [tool.scikit-build.cmake.define] -VACUUM_GRIPPER = "ON" +LIBFRANKA_VER = "0x000902" diff --git a/src/libfranka.cpp b/src/libfranka.cpp index c109750..3c2033b 100644 --- a/src/libfranka.cpp +++ b/src/libfranka.cpp @@ -10,10 +10,14 @@ #include -#ifdef VACUUM_GRIPPER +#if LIBFRANKA_VER >= 0x000800 #include #endif +#if LIBFRANKA_VER >= 0x000e00 +#include +#endif + #define PYBIND11_DETAILED_ERROR_MESSAGES 1 #define def_readonly_franka_robotstate(name) \ @@ -245,6 +249,18 @@ PYBIND11_MODULE(libfranka, m) { &franka::Model::gravity, py::const_), py::arg("robot_state"), py::arg("gravity_earth") = gravity_earth); + #if LIBFRANKA_VER >= 0x000e00 + py::class_(m, "RobotModel") + .def(py::init(), + py::arg("urdf")) + .def("coriolis", &franka::RobotModel::coriolis, + py::arg("q"), py::arg("dq"), py::arg("i_total"), py::arg("m_total"), py::arg("f_x_ctotal"), py::arg("c_ne")) + .def("gravity", &franka::RobotModel::gravity, + py::arg("q"), py::arg("g_earth"), py::arg("m_total"), py::arg("f_x_ctotal"), py::arg("g_ne")) + .def("mass", &franka::RobotModel::mass, + py::arg("q"), py::arg("i_total"), py::arg("m_total"), py::arg("f_x_ctotal"), py::arg("m_ne")); + #endif + py::enum_(m, "RealtimeConfig") .value("kEnforce", franka::RealtimeConfig::kEnforce) .value("kIgnore", franka::RealtimeConfig::kIgnore); @@ -307,7 +323,11 @@ PYBIND11_MODULE(libfranka, m) { py::arg("log_size") = 50) .def("read", &franka::Robot::read) .def("read_once", &franka::Robot::readOnce) + #if LIBFRANKA_VER >= 0x000e00 + .def("load_model", py::overload_cast<>(&franka::Robot::loadModel)) + #else .def("load_model", &franka::Robot::loadModel) + #endif .def("server_version", &franka::Robot::serverVersion) .def("control", py::overload_cast()) .def("read_once", &franka::Gripper::readOnce); -#ifdef VACUUM_GRIPPER + #if LIBFRANKA_VER >= 0x000800 py::enum_(m, "VacuumGripperDeviceStatus") .value("kGreen", franka::VacuumGripperDeviceStatus::kGreen) .value("kYellow", franka::VacuumGripperDeviceStatus::kYellow) diff --git a/src/panda_py/__init__.py b/src/panda_py/__init__.py index daba58f..ac30aa2 100644 --- a/src/panda_py/__init__.py +++ b/src/panda_py/__init__.py @@ -32,7 +32,7 @@ 'fk', 'ik', 'ik_full', 'Desk', 'TOKEN_PATH' ] -__version__ = '0.8.1' +__version__ = '1.0.0' _logger = logging.getLogger('desk') diff --git a/src/panda_py/__init__.pyi b/src/panda_py/__init__.pyi index 439efad..6224874 100644 --- a/src/panda_py/__init__.pyi +++ b/src/panda_py/__init__.pyi @@ -234,5 +234,5 @@ class Token: TOKEN_PATH: str = '~/.panda_py/token.conf' -__version__: str = '0.8.1' +__version__: str = '1.0.0' _logger: logging.Logger # value =