diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 0c60055b6..b62f748dd 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -29,16 +29,19 @@ RUN DEBIAN_FRONTEND=noninteractive apt-get update -q && \ RUN source "/opt/ros/${ROS_DISTRO}/setup.bash" +ARG SPOT_SDK_VERSION="4.1.0" +ARG SPOT_MSG_VERSION="${SPOT_SDK_VERSION}-4" + # Install bosdyn_msgs package -RUN curl -sL https://github.com/bdaiinstitute/bosdyn_msgs/releases/download/4.0.2/ros-humble-bosdyn_msgs_4.0.2-jammy_amd64.run --output /tmp/ros-humble-bosdyn_msgs_4.0.2-jammy_amd64.run --silent \ - && chmod +x /tmp/ros-humble-bosdyn_msgs_4.0.2-jammy_amd64.run \ - && ((yes || true) | /tmp/ros-humble-bosdyn_msgs_4.0.2-jammy_amd64.run) \ - && rm /tmp/ros-humble-bosdyn_msgs_4.0.2-jammy_amd64.run +RUN curl -sL https://github.com/bdaiinstitute/bosdyn_msgs/releases/download/${SPOT_MSG_VERSION}/ros-humble-bosdyn_msgs_${SPOT_MSG_VERSION}-jammy_amd64.run --output /tmp/ros-humble-bosdyn_msgs_${SPOT_MSG_VERSION}-jammy_amd64.run --silent \ + && chmod +x /tmp/ros-humble-bosdyn_msgs_${SPOT_MSG_VERSION}-jammy_amd64.run \ + && ((yes || true) | /tmp/ros-humble-bosdyn_msgs_${SPOT_MSG_VERSION}-jammy_amd64.run) \ + && rm /tmp/ros-humble-bosdyn_msgs_${SPOT_MSG_VERSION}-jammy_amd64.run # Install spot_cpp_sdk package -RUN curl -sL https://github.com/bdaiinstitute/spot-cpp-sdk/releases/download/v4.0.2/spot-cpp-sdk_4.0.2_amd64.deb --output /tmp/spot-cpp-sdk_4.0.2_amd64.deb --silent \ - && dpkg -i /tmp/spot-cpp-sdk_4.0.2_amd64.deb \ - && rm /tmp/spot-cpp-sdk_4.0.2_amd64.deb +RUN curl -sL https://github.com/bdaiinstitute/spot-cpp-sdk/releases/download/v${SPOT_SDK_VERSION}/spot-cpp-sdk_${SPOT_SDK_VERSION}_amd64.deb --output /tmp/spot-cpp-sdk_${SPOT_SDK_VERSION}_amd64.deb --silent \ + && dpkg -i /tmp/spot-cpp-sdk_${SPOT_SDK_VERSION}_amd64.deb \ + && rm /tmp/spot-cpp-sdk_${SPOT_SDK_VERSION}_amd64.deb # Install bosdyn_msgs missing dependencies RUN python -m pip install --no-cache-dir --upgrade pip==22.3.1 \ @@ -46,11 +49,11 @@ RUN python -m pip install --no-cache-dir --upgrade pip==22.3.1 \ numpy==1.24.1 \ pytest-cov==4.1.0 \ pytest-xdist==3.5.0 \ - bosdyn-api==4.0.2 \ - bosdyn-core==4.0.2 \ - bosdyn-client==4.0.2 \ - bosdyn-mission==4.0.2 \ - bosdyn-choreography-client==4.0.2 \ + bosdyn-api==${SPOT_SDK_VERSION} \ + bosdyn-core==${SPOT_SDK_VERSION} \ + bosdyn-client==${SPOT_SDK_VERSION} \ + bosdyn-mission==${SPOT_SDK_VERSION} \ + bosdyn-choreography-client==${SPOT_SDK_VERSION} \ pip cache purge # Install spot_wrapper requirements diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b519b484b..f3cfe8d92 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,8 +34,6 @@ jobs: strategy: matrix: config: - - { python: "3.8" } - - { python: "3.9" } - { python: "3.10" } steps: - name: Checkout repository diff --git a/README.md b/README.md index 35cd89e1b..386dfc80f 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@

Spot ROS 2 Driver

- + @@ -23,7 +23,7 @@ # Overview This is a ROS 2 package for Boston Dynamics' Spot. The package contains all necessary topics, services and actions to teleoperate or navigate Spot. -This package is derived from this [ROS 1 package](https://github.com/heuristicus/spot_ros). This package currently corresponds to version 4.0.2 of the [spot-sdk](https://github.com/boston-dynamics/spot-sdk/releases/tag/v4.0.2). +This package is derived from this [ROS 1 package](https://github.com/heuristicus/spot_ros). This package currently corresponds to version 4.1.0 of the [spot-sdk](https://github.com/boston-dynamics/spot-sdk/releases/tag/v4.1.0). ## Prerequisites This package is tested for Ubuntu 22.04 and ROS 2 Humble, which can be installed following [this guide](https://docs.ros.org/en/humble/Installation/Ubuntu-Install-Debians.html). diff --git a/install_spot_ros2.sh b/install_spot_ros2.sh index 1bd760834..f830ff050 100755 --- a/install_spot_ros2.sh +++ b/install_spot_ros2.sh @@ -1,6 +1,6 @@ ARCH="amd64" -SDK_VERSION="4.0.2" -MSG_VERSION="${SDK_VERSION}" +SDK_VERSION="4.1.0" +MSG_VERSION="${SDK_VERSION}-4" ROS_DISTRO=humble HELP=$'--arm64: Installs ARM64 version' REQUIREMENTS_FILE=spot_wrapper/requirements.txt diff --git a/pyproject.toml b/pyproject.toml index ac03a14d5..54b03cd81 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,7 +29,7 @@ exclude = [ ] line-length = 120 dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$" -target-version = "py38" +target-version = "py310" [tool.ruff.per-file-ignores] "__init__.py" = ["F401"] @@ -39,7 +39,7 @@ max-complexity = 10 [tool.black] line-length = 120 -target-version = ['py38'] +target-version = ['py310'] include = '\.pyi?$' force-exclude = ''' /( @@ -48,7 +48,7 @@ force-exclude = ''' preview = true [tool.mypy] -python_version = "3.8" +python_version = "3.10" disallow_untyped_defs = true ignore_missing_imports = true explicit_package_bases = true diff --git a/spot_driver/CMakeLists.txt b/spot_driver/CMakeLists.txt index 6894401c2..bcee60cd5 100644 --- a/spot_driver/CMakeLists.txt +++ b/spot_driver/CMakeLists.txt @@ -1,7 +1,5 @@ cmake_minimum_required(VERSION 3.22) -list(APPEND CMAKE_PREFIX_PATH /opt/spot-cpp-sdk) - project(spot_driver) if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") @@ -18,6 +16,7 @@ endif() set(THIS_PACKAGE_INCLUDE_ROS_DEPENDS bosdyn_api_msgs + bosdyn_cmake_module bosdyn_spot_api_msgs cv_bridge geometry_msgs @@ -36,12 +35,14 @@ set(THIS_PACKAGE_INCLUDE_ROS_DEPENDS find_package(ament_cmake REQUIRED) find_package(ament_cmake_python REQUIRED) -find_package(bosdyn REQUIRED) -find_package(OpenCV 4 REQUIRED) + foreach(Dependency IN ITEMS ${THIS_PACKAGE_INCLUDE_ROS_DEPENDS}) find_package(${Dependency} REQUIRED) endforeach() +find_package(bosdyn REQUIRED) +find_package(OpenCV 4 REQUIRED) + ### # Spot API ### @@ -85,7 +86,7 @@ target_include_directories(spot_api PUBLIC $ ) -target_link_libraries(spot_api PUBLIC bosdyn::bosdyn_client_static) +target_link_libraries(spot_api PUBLIC bosdyn::bosdyn_client) set_property(TARGET spot_api PROPERTY POSITION_INDEPENDENT_CODE ON) ament_target_dependencies(spot_api PUBLIC ${THIS_PACKAGE_INCLUDE_ROS_DEPENDS}) diff --git a/spot_driver/package.xml b/spot_driver/package.xml index 6e4981454..859d5c716 100644 --- a/spot_driver/package.xml +++ b/spot_driver/package.xml @@ -12,6 +12,7 @@ rosidl_default_generators bosdyn + bosdyn_cmake_module bosdyn_msgs common_interfaces cv_bridge diff --git a/spot_ros2_control/CMakeLists.txt b/spot_ros2_control/CMakeLists.txt index a6c878f7b..0de1af86b 100644 --- a/spot_ros2_control/CMakeLists.txt +++ b/spot_ros2_control/CMakeLists.txt @@ -5,9 +5,6 @@ cmake_minimum_required(VERSION 3.22) # This is here so we can use jthread from C++ 20 set(CMAKE_CXX_STANDARD 20) -# Taken from spot_driver CMakeLists -list(APPEND CMAKE_PREFIX_PATH /opt/spot-cpp-sdk) - project(spot_ros2_control) if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") @@ -16,8 +13,8 @@ endif() # Dependencies find_package(ament_cmake REQUIRED) -find_package(bosdyn REQUIRED) set(THIS_PACKAGE_INCLUDE_DEPENDS + bosdyn_cmake_module hardware_interface controller_manager pluginlib @@ -31,6 +28,7 @@ set(THIS_PACKAGE_INCLUDE_DEPENDS foreach(Dependency IN ITEMS ${THIS_PACKAGE_INCLUDE_DEPENDS}) find_package(${Dependency} REQUIRED) endforeach() +find_package(bosdyn REQUIRED) if(BUILD_TESTING) find_package(ament_lint_auto REQUIRED) @@ -51,7 +49,7 @@ target_include_directories(spot_ros2_control PUBLIC $ $ ) -target_link_libraries(spot_ros2_control PUBLIC bosdyn::bosdyn_client_static) +target_link_libraries(spot_ros2_control PUBLIC bosdyn::bosdyn_client) ament_target_dependencies( spot_ros2_control PUBLIC ${THIS_PACKAGE_INCLUDE_DEPENDS} diff --git a/spot_ros2_control/hardware/src/spot_hardware_interface.cpp b/spot_ros2_control/hardware/src/spot_hardware_interface.cpp index e5106dcd1..03a1a2ac6 100644 --- a/spot_ros2_control/hardware/src/spot_hardware_interface.cpp +++ b/spot_ros2_control/hardware/src/spot_hardware_interface.cpp @@ -487,8 +487,10 @@ bool SpotHardware::start_command_stream() { return false; } - joint_cmd->mutable_gains()->mutable_k_q_p()->Assign(kp.begin(), kp.end()); - joint_cmd->mutable_gains()->mutable_k_qd_p()->Assign(kd.begin(), kd.end()); + joint_cmd->mutable_gains()->mutable_k_q_p()->Clear(); + joint_cmd->mutable_gains()->mutable_k_q_p()->Add(kp.begin(), kp.end()); + joint_cmd->mutable_gains()->mutable_k_qd_p()->Clear(); + joint_cmd->mutable_gains()->mutable_k_qd_p()->Add(kd.begin(), kd.end()); // Let it extrapolate the command a little joint_cmd->mutable_extrapolation_duration()->CopyFrom( @@ -518,9 +520,12 @@ void SpotHardware::send_command(const JointStates& joint_commands) { // build protobuf auto* joint_cmd = joint_request_.mutable_joint_command(); - joint_cmd->mutable_position()->Assign(position.begin(), position.end()); - joint_cmd->mutable_velocity()->Assign(velocity.begin(), velocity.end()); - joint_cmd->mutable_load()->Assign(load.begin(), load.end()); + joint_cmd->mutable_position()->Clear(); + joint_cmd->mutable_position()->Add(position.begin(), position.end()); + joint_cmd->mutable_velocity()->Clear(); + joint_cmd->mutable_velocity()->Add(velocity.begin(), velocity.end()); + joint_cmd->mutable_load()->Clear(); + joint_cmd->mutable_load()->Add(load.begin(), load.end()); if (endpoint_ == nullptr) { auto endpoint_result = robot_->StartTimeSyncAndGetEndpoint(); diff --git a/spot_ros2_control/package.xml b/spot_ros2_control/package.xml index 1f1e8a670..eb3cb80a7 100644 --- a/spot_ros2_control/package.xml +++ b/spot_ros2_control/package.xml @@ -17,6 +17,7 @@ Copyright (c) 2024 Boston Dynamics AI Institute LLC. All rights reserved. rclcpp rclcpp_lifecycle bosdyn + bosdyn_cmake_module std_msgs sensor_msgs diff --git a/spot_wrapper b/spot_wrapper index bde75c2cf..5c01ea7b7 160000 --- a/spot_wrapper +++ b/spot_wrapper @@ -1 +1 @@ -Subproject commit bde75c2cf9e6499802c90066fdad9be9368274a8 +Subproject commit 5c01ea7b7ae26116f64719ff0b21b52eb814df7e