diff --git a/.clang-format b/.clang-format index 9a6ec50..4a79087 100644 --- a/.clang-format +++ b/.clang-format @@ -1,75 +1,20 @@ --- -BasedOnStyle: Google -ColumnLimit: 120 -MaxEmptyLinesToKeep: 1 -SortIncludes: false +Language: Cpp +BasedOnStyle: Google -Standard: Auto -IndentWidth: 2 -TabWidth: 2 -UseTab: Never AccessModifierOffset: -2 -ConstructorInitializerIndentWidth: 2 -NamespaceIndentation: None -ContinuationIndentWidth: 4 -IndentCaseLabels: true -IndentFunctionDeclarationAfterType: false - -AlignEscapedNewlinesLeft: false -AlignTrailingComments: true - -AllowAllParametersOfDeclarationOnNextLine: false -ExperimentalAutoDetectBinPacking: false -ObjCSpaceBeforeProtocolList: true -Cpp11BracedListStyle: false - -AllowShortBlocksOnASingleLine: true -AllowShortIfStatementsOnASingleLine: false -AllowShortLoopsOnASingleLine: false -AllowShortFunctionsOnASingleLine: None -AllowShortCaseLabelsOnASingleLine: false - -AlwaysBreakTemplateDeclarations: true -AlwaysBreakBeforeMultilineStrings: false -BreakBeforeBinaryOperators: false -BreakBeforeTernaryOperators: false -BreakConstructorInitializersBeforeComma: true - -BinPackParameters: true -ConstructorInitializerAllOnOneLineOrOnePerLine: true -DerivePointerBinding: false -PointerBindsToType: true - -PenaltyExcessCharacter: 50 -PenaltyBreakBeforeFirstCallParameter: 30 -PenaltyBreakComment: 1000 -PenaltyBreakFirstLessLess: 10 -PenaltyBreakString: 100 -PenaltyReturnTypeOnItsOwnLine: 50 - -SpacesBeforeTrailingComments: 2 -SpacesInParentheses: false -SpacesInAngles: false -SpaceInEmptyParentheses: false -SpacesInCStyleCastParentheses: false -SpaceAfterCStyleCast: false -SpaceAfterControlStatementKeyword: true -SpaceBeforeAssignmentOperators: true - -# Configure each individual brace in BraceWrapping -BreakBeforeBraces: Custom - -# Control of individual brace wrapping cases +AlignAfterOpenBracket: AlwaysBreak BraceWrapping: - AfterCaseLabel: true - AfterClass: true - AfterControlStatement: true - AfterEnum: true - AfterFunction: true - AfterNamespace: true - AfterStruct: true - AfterUnion: true - BeforeCatch: true - BeforeElse: true - IndentBraces: false + AfterClass: true + AfterFunction: true + AfterNamespace: true + AfterStruct: true + AfterEnum: true +BreakBeforeBraces: Custom +ColumnLimit: 100 +ConstructorInitializerIndentWidth: 0 +ContinuationIndentWidth: 2 +DerivePointerAlignment: false +PointerAlignment: Middle +ReflowComments: false ... diff --git a/.codespell-ignore-words.txt b/.codespell-ignore-words.txt new file mode 100644 index 0000000..e69de29 diff --git a/.flake8 b/.flake8 new file mode 100644 index 0000000..14e35c3 --- /dev/null +++ b/.flake8 @@ -0,0 +1,10 @@ +[flake8] +max-line-length = 88 + +# Report all errors starting with E, F, W or C - or Bugbear's B590 rule, which is a "pragmatic" version of E501 (line too long) +select = E,F,W,C,B590 + +# Ignore W503 - Line break occurred before a binary operator - because this error is introduced by Black formatter. +# Ignore E203 - whitespace before ':' - because Black includes spaces in formatting slice expressions. +# Ignore E501 - line too long - in favor of B590, which is more forgiving of long strings and comments that would be silly to break up. +extend-ignore = W503, E203, E501 diff --git a/.github/workflows/README.md b/.github/workflows/README.md new file mode 100644 index 0000000..103f7ad --- /dev/null +++ b/.github/workflows/README.md @@ -0,0 +1,72 @@ + +ROS2 Distro | Branch | Build status | Documentation | Released packages +:---------: | :----: | :----------: | :-----------: | :---------------: +**Rolling** | [`rolling`](https://github.com/PickNikRobotics/ros2_robotiq_gripper/tree/rolling) | [![Rolling Binary Build](https://github.com/PickNikRobotics/ros2_robotiq_gripper/actions/workflows/rolling-binary-build-main.yml/badge.svg?branch=main)](https://github.com/PickNikRobotics/ros2_robotiq_gripper/actions/workflows/rolling-binary-build-main.yml?branch=main)
[![Rolling Binary Build](https://github.com/PickNikRobotics/ros2_robotiq_gripper/actions/workflows/rolling-binary-build-testing.yml/badge.svg?branch=main)](https://github.com/PickNikRobotics/ros2_robotiq_gripper/actions/workflows/rolling-binary-build-testing.yml?branch=main)
[![Rolling Semi-Binary Build](https://github.com/PickNikRobotics/ros2_robotiq_gripper/actions/workflows/rolling-semi-binary-build-main.yml/badge.svg?branch=main)](https://github.com/PickNikRobotics/ros2_robotiq_gripper/actions/workflows/rolling-semi-binary-build-main.yml?branch=main)
[![Rolling Semi-Binary Build](https://github.com/PickNikRobotics/ros2_robotiq_gripper/actions/workflows/rolling-semi-binary-build-testing.yml/badge.svg?branch=main)](https://github.com/PickNikRobotics/ros2_robotiq_gripper/actions/workflows/rolling-semi-binary-build-testing.yml?branch=main)
[![Rolling Source Build](https://github.com/PickNikRobotics/ros2_robotiq_gripper/actions/workflows/rolling-source-build.yml/badge.svg?branch=main)](https://github.com/PickNikRobotics/ros2_robotiq_gripper/actions/workflows/rolling-source-build.yml?branch=main) | [![Doxygen Doc Deployment](https://github.com/PickNikRobotics/ros2_robotiq_gripper/actions/workflows/doxygen-deploy.yml/badge.svg)](https://github.com/PickNikRobotics/ros2_robotiq_gripper/actions/workflows/doxygen-deploy.yml)
[Generated Doc](https://PickNikRobotics.github.io/ros2_robotiq_gripper_Documentation/rolling/html/index.html) | [ros2_robotiq_gripper](https://index.ros.org/p/ros2_robotiq_gripper/#rolling) + +## Build status + + +### Explanation of different build types + +**NOTE**: There are three build stages checking current and future compatibility of the package. + +[Detailed build status](.github/workflows/README.md) + +1. Binary builds - against released packages (main and testing) in ROS distributions. Shows that direct local build is possible. + + Uses repos file: `$NAME$-not-released..repos` + +1. Semi-binary builds - against released core ROS packages (main and testing), but the immediate dependencies are pulled from source. + Shows that local build with dependencies is possible and if fails there we can expect that after the next package sync we will not be able to build. + + Uses repos file: `$NAME$.repos` + +1. Source build - also core ROS packages are build from source. It shows potential issues in the mid future. + +ROS2 Distro | Branch | Build status | Documentation | Released packages +:---------: | :----: | :----------: | :-----------: | :---------------: +**Humble** | [`humble`](https://github.com/PickNikRobotics/ros2_robotiq_gripper/tree/humble) | [![Humble Binary Build](https://github.com/PickNikRobotics/ros2_robotiq_gripper/actions/workflows/humble-binary-build-main.yml/badge.svg?branch=main)](https://github.com/PickNikRobotics/ros2_robotiq_gripper/actions/workflows/humble-binary-build-main.yml?branch=main)
[![Humble Binary Build](https://github.com/PickNikRobotics/ros2_robotiq_gripper/actions/workflows/humble-binary-build-testing.yml/badge.svg?branch=main)](https://github.com/PickNikRobotics/ros2_robotiq_gripper/actions/workflows/humble-binary-build-testing.yml?branch=main)
[![Humble Semi-Binary Build](https://github.com/PickNikRobotics/ros2_robotiq_gripper/actions/workflows/humble-semi-binary-build-main.yml/badge.svg?branch=main)](https://github.com/PickNikRobotics/ros2_robotiq_gripper/actions/workflows/humble-semi-binary-build-main.yml?branch=main)
[![Humble Semi-Binary Build](https://github.com/PickNikRobotics/ros2_robotiq_gripper/actions/workflows/humble-semi-binary-build-testing.yml/badge.svg?branch=main)](https://github.com/PickNikRobotics/ros2_robotiq_gripper/actions/workflows/humble-semi-binary-build-testing.yml?branch=main)
[![Humble Source Build](https://github.com/PickNikRobotics/ros2_robotiq_gripper/actions/workflows/humble-source-build.yml/badge.svg?branch=main)](https://github.com/PickNikRobotics/ros2_robotiq_gripper/actions/workflows/humble-source-build.yml?branch=main) | [![Doxygen Doc Deployment](https://github.com/PickNikRobotics/ros2_robotiq_gripper/actions/workflows/doxygen-deploy.yml/badge.svg)](https://github.com/PickNikRobotics/ros2_robotiq_gripper/actions/workflows/doxygen-deploy.yml)
[Generated Doc](https://PickNikRobotics.github.io/ros2_robotiq_gripper_Documentation/humble/html/index.html) | [ros2_robotiq_gripper](https://index.ros.org/p/ros2_robotiq_gripper/#humble) + +## Build status + + +### Explanation of different build types + +**NOTE**: There are three build stages checking current and future compatibility of the package. + +[Detailed build status](.github/workflows/README.md) + +1. Binary builds - against released packages (main and testing) in ROS distributions. Shows that direct local build is possible. + + Uses repos file: `$NAME$-not-released..repos` + +1. Semi-binary builds - against released core ROS packages (main and testing), but the immediate dependencies are pulled from source. + Shows that local build with dependencies is possible and if fails there we can expect that after the next package sync we will not be able to build. + + Uses repos file: `$NAME$.repos` + +1. Source build - also core ROS packages are build from source. It shows potential issues in the mid future. + +ROS2 Distro | Branch | Build status | Documentation | Released packages +:---------: | :----: | :----------: | :-----------: | :---------------: +**Iron** | [`iron`](https://github.com/PickNikRobotics/ros2_robotiq_gripper/tree/iron) | [![Iron Binary Build](https://github.com/PickNikRobotics/ros2_robotiq_gripper/actions/workflows/iron-binary-build-main.yml/badge.svg?branch=main)](https://github.com/PickNikRobotics/ros2_robotiq_gripper/actions/workflows/iron-binary-build-main.yml?branch=main)
[![Iron Binary Build](https://github.com/PickNikRobotics/ros2_robotiq_gripper/actions/workflows/iron-binary-build-testing.yml/badge.svg?branch=main)](https://github.com/PickNikRobotics/ros2_robotiq_gripper/actions/workflows/iron-binary-build-testing.yml?branch=main)
[![Iron Semi-Binary Build](https://github.com/PickNikRobotics/ros2_robotiq_gripper/actions/workflows/iron-semi-binary-build-main.yml/badge.svg?branch=main)](https://github.com/PickNikRobotics/ros2_robotiq_gripper/actions/workflows/iron-semi-binary-build-main.yml?branch=main)
[![Iron Semi-Binary Build](https://github.com/PickNikRobotics/ros2_robotiq_gripper/actions/workflows/iron-semi-binary-build-testing.yml/badge.svg?branch=main)](https://github.com/PickNikRobotics/ros2_robotiq_gripper/actions/workflows/iron-semi-binary-build-testing.yml?branch=main)
[![Iron Source Build](https://github.com/PickNikRobotics/ros2_robotiq_gripper/actions/workflows/iron-source-build.yml/badge.svg?branch=main)](https://github.com/PickNikRobotics/ros2_robotiq_gripper/actions/workflows/iron-source-build.yml?branch=main) | [![Doxygen Doc Deployment](https://github.com/PickNikRobotics/ros2_robotiq_gripper/actions/workflows/doxygen-deploy.yml/badge.svg)](https://github.com/PickNikRobotics/ros2_robotiq_gripper/actions/workflows/doxygen-deploy.yml)
[Generated Doc](https://PickNikRobotics.github.io/ros2_robotiq_gripper_Documentation/iron/html/index.html) | [ros2_robotiq_gripper](https://index.ros.org/p/ros2_robotiq_gripper/#iron) + +## Build status + + +### Explanation of different build types + +**NOTE**: There are three build stages checking current and future compatibility of the package. + +[Detailed build status](.github/workflows/README.md) + +1. Binary builds - against released packages (main and testing) in ROS distributions. Shows that direct local build is possible. + + Uses repos file: `$NAME$-not-released..repos` + +1. Semi-binary builds - against released core ROS packages (main and testing), but the immediate dependencies are pulled from source. + Shows that local build with dependencies is possible and if fails there we can expect that after the next package sync we will not be able to build. + + Uses repos file: `$NAME$.repos` + +1. Source build - also core ROS packages are build from source. It shows potential issues in the mid future. diff --git a/.github/workflows/ci-coverage-build.yml b/.github/workflows/ci-coverage-build.yml new file mode 100644 index 0000000..336fb7d --- /dev/null +++ b/.github/workflows/ci-coverage-build.yml @@ -0,0 +1,50 @@ +name: Coverage Build +on: + workflow_dispatch: + branches: + - main + pull_request: + branches: + - main + +jobs: + coverage: + name: coverage build + runs-on: ubuntu-22.04 + strategy: + fail-fast: false + env: + ROS_DISTRO: rolling + steps: + - uses: ros-tooling/setup-ros@0.3.4 + with: + required-ros-distributions: ${{ env.ROS_DISTRO }} + - uses: actions/checkout@v3 + - uses: ros-tooling/action-ros-ci@0.2.6 + with: + target-ros2-distro: ${{ env.ROS_DISTRO }} + import-token: ${{ secrets.GITHUB_TOKEN }} + # build all packages listed in the meta package + package-name: + robotiq_driver + robotiq_controllers + robotiq_description + + vcs-repo-file-url: | + https://raw.githubusercontent.com/${{ github.repository }}/${{ github.sha }}/ros2_robotiq_gripper-not-released.${{ env.ROS_DISTRO }}.repos?token=${{ secrets.GITHUB_TOKEN }} + colcon-defaults: | + { + "build": { + "mixin": ["coverage-gcc"] + } + } + colcon-mixin-repository: https://raw.githubusercontent.com/colcon/colcon-mixin-repository/master/index.yaml + - uses: codecov/codecov-action@v3.1.0 + with: + file: ros_ws/lcov/total_coverage.info + flags: unittests + name: codecov-umbrella + - uses: actions/upload-artifact@v3.1.0 + with: + name: colcon-logs-coverage-rolling + path: ros_ws/log diff --git a/.github/workflows/ci-format.yml b/.github/workflows/ci-format.yml new file mode 100644 index 0000000..3d60336 --- /dev/null +++ b/.github/workflows/ci-format.yml @@ -0,0 +1,26 @@ +# This is a format job. Pre-commit has a first-party GitHub action, so we use +# that: https://github.com/pre-commit/action + +name: Format + +on: + workflow_dispatch: + pull_request: + push: + branches: + - main + +jobs: + pre-commit: + name: Format + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4.4.0 + with: + python-version: '3.10' + - name: Install system hooks + run: sudo apt install -qq clang-format-14 cppcheck + - uses: pre-commit/action@v3.0.0 + with: + extra_args: --all-files --hook-stage manual diff --git a/.github/workflows/ci-ros-lint.yml b/.github/workflows/ci-ros-lint.yml new file mode 100644 index 0000000..e27cf4e --- /dev/null +++ b/.github/workflows/ci-ros-lint.yml @@ -0,0 +1,45 @@ +name: ROS Lint +on: + pull_request: + +jobs: + ament_lint: + name: ament_${{ matrix.linter }} + runs-on: ubuntu-20.04 + strategy: + fail-fast: false + matrix: + linter: [cppcheck, copyright, lint_cmake] + steps: + - uses: actions/checkout@v3 + - uses: ros-tooling/setup-ros@v0.2 + - uses: ros-tooling/action-ros-lint@v0.1 + with: + distribution: rolling + linter: ${{ matrix.linter }} + package-name: + robotiq_driver + robotiq_controllers + robotiq_description + + + ament_lint_100: + name: ament_${{ matrix.linter }} + runs-on: ubuntu-20.04 + strategy: + fail-fast: false + matrix: + linter: [cpplint] + steps: + - uses: actions/checkout@v3 + - uses: ros-tooling/setup-ros@v0.2 + - uses: ros-tooling/action-ros-lint@v0.1 + with: + distribution: rolling + linter: cpplint + arguments: "--linelength=100 --filter=-whitespace/newline" + package-name: + robotiq_driver + robotiq_controllers + robotiq_description + ros2_robotiq_gripper diff --git a/.github/workflows/humble-binary-build-main.yml b/.github/workflows/humble-binary-build-main.yml new file mode 100644 index 0000000..fd97c85 --- /dev/null +++ b/.github/workflows/humble-binary-build-main.yml @@ -0,0 +1,26 @@ +name: Humble Binary Build - main +# author: Denis Štogl +# description: 'Build & test all dependencies from released (binary) packages.' + +on: + workflow_dispatch: + branches: + - main + pull_request: + branches: + - main + push: + branches: + - main + schedule: + # Run every morning to detect flakiness and broken dependencies + - cron: '03 1 * * *' + +jobs: + binary: + uses: ./.github/workflows/reusable-industrial-ci-with-cache.yml + with: + ros_distro: humble + ros_repo: main + upstream_workspace: ros2_robotiq_gripper-not-released.humble.repos + ref_for_scheduled_build: main diff --git a/.github/workflows/humble-binary-build-testing.yml b/.github/workflows/humble-binary-build-testing.yml new file mode 100644 index 0000000..36076de --- /dev/null +++ b/.github/workflows/humble-binary-build-testing.yml @@ -0,0 +1,26 @@ +name: Humble Binary Build - testing +# author: Denis Štogl +# description: 'Build & test all dependencies from released (binary) packages.' + +on: + workflow_dispatch: + branches: + - main + pull_request: + branches: + - main + push: + branches: + - main + schedule: + # Run every morning to detect flakiness and broken dependencies + - cron: '03 1 * * *' + +jobs: + binary: + uses: ./.github/workflows/reusable-industrial-ci-with-cache.yml + with: + ros_distro: humble + ros_repo: testing + upstream_workspace: ros2_robotiq_gripper-not-released.humble.repos + ref_for_scheduled_build: main diff --git a/.github/workflows/humble-semi-binary-build-main.yml b/.github/workflows/humble-semi-binary-build-main.yml new file mode 100644 index 0000000..17ababa --- /dev/null +++ b/.github/workflows/humble-semi-binary-build-main.yml @@ -0,0 +1,25 @@ +name: Humble Semi-Binary Build - main +# description: 'Build & test that compiles the main dependencies from source.' + +on: + workflow_dispatch: + branches: + - main + pull_request: + branches: + - main + push: + branches: + - main + schedule: + # Run every morning to detect flakiness and broken dependencies + - cron: '33 1 * * *' + +jobs: + semi_binary: + uses: ./.github/workflows/reusable-industrial-ci-with-cache.yml + with: + ros_distro: humble + ros_repo: main + upstream_workspace: ros2_robotiq_gripper.humble.repos + ref_for_scheduled_build: main diff --git a/.github/workflows/humble-semi-binary-build-testing.yml b/.github/workflows/humble-semi-binary-build-testing.yml new file mode 100644 index 0000000..0292176 --- /dev/null +++ b/.github/workflows/humble-semi-binary-build-testing.yml @@ -0,0 +1,25 @@ +name: Humble Semi-Binary Build - testing +# description: 'Build & test that compiles the main dependencies from source.' + +on: + workflow_dispatch: + branches: + - main + pull_request: + branches: + - main + push: + branches: + - main + schedule: + # Run every morning to detect flakiness and broken dependencies + - cron: '33 1 * * *' + +jobs: + semi_binary: + uses: ./.github/workflows/reusable-industrial-ci-with-cache.yml + with: + ros_distro: humble + ros_repo: testing + upstream_workspace: ros2_robotiq_gripper.humble.repos + ref_for_scheduled_build: main diff --git a/.github/workflows/humble-source-build.yml b/.github/workflows/humble-source-build.yml new file mode 100644 index 0000000..9869d1f --- /dev/null +++ b/.github/workflows/humble-source-build.yml @@ -0,0 +1,19 @@ +name: Humble Source Build +on: + workflow_dispatch: + branches: + - main + push: + branches: + - main + schedule: + # Run every day to detect flakiness and broken dependencies + - cron: '03 3 * * *' + +jobs: + source: + uses: ./.github/workflows/reusable-ros-tooling-source-build.yml + with: + ros_distro: humble + ref: main + ros2_repo_branch: humble diff --git a/.github/workflows/iron-binary-build-main.yml b/.github/workflows/iron-binary-build-main.yml new file mode 100644 index 0000000..cea9495 --- /dev/null +++ b/.github/workflows/iron-binary-build-main.yml @@ -0,0 +1,26 @@ +name: Iron Binary Build - main +# author: Denis Štogl +# description: 'Build & test all dependencies from released (binary) packages.' + +on: + workflow_dispatch: + branches: + - main + pull_request: + branches: + - main + push: + branches: + - main + schedule: + # Run every morning to detect flakiness and broken dependencies + - cron: '03 1 * * *' + +jobs: + binary: + uses: ./.github/workflows/reusable-industrial-ci-with-cache.yml + with: + ros_distro: iron + ros_repo: main + upstream_workspace: ros2_robotiq_gripper-not-released.iron.repos + ref_for_scheduled_build: main diff --git a/.github/workflows/iron-binary-build-testing.yml b/.github/workflows/iron-binary-build-testing.yml new file mode 100644 index 0000000..9470611 --- /dev/null +++ b/.github/workflows/iron-binary-build-testing.yml @@ -0,0 +1,26 @@ +name: Iron Binary Build - testing +# author: Denis Štogl +# description: 'Build & test all dependencies from released (binary) packages.' + +on: + workflow_dispatch: + branches: + - main + pull_request: + branches: + - main + push: + branches: + - main + schedule: + # Run every morning to detect flakiness and broken dependencies + - cron: '03 1 * * *' + +jobs: + binary: + uses: ./.github/workflows/reusable-industrial-ci-with-cache.yml + with: + ros_distro: iron + ros_repo: testing + upstream_workspace: ros2_robotiq_gripper-not-released.iron.repos + ref_for_scheduled_build: main diff --git a/.github/workflows/iron-semi-binary-build-main.yml b/.github/workflows/iron-semi-binary-build-main.yml new file mode 100644 index 0000000..ac9efb5 --- /dev/null +++ b/.github/workflows/iron-semi-binary-build-main.yml @@ -0,0 +1,25 @@ +name: Iron Semi-Binary Build - main +# description: 'Build & test that compiles the main dependencies from source.' + +on: + workflow_dispatch: + branches: + - main + pull_request: + branches: + - main + push: + branches: + - main + schedule: + # Run every morning to detect flakiness and broken dependencies + - cron: '33 1 * * *' + +jobs: + semi_binary: + uses: ./.github/workflows/reusable-industrial-ci-with-cache.yml + with: + ros_distro: iron + ros_repo: main + upstream_workspace: ros2_robotiq_gripper.iron.repos + ref_for_scheduled_build: main diff --git a/.github/workflows/iron-semi-binary-build-testing.yml b/.github/workflows/iron-semi-binary-build-testing.yml new file mode 100644 index 0000000..ec93f8f --- /dev/null +++ b/.github/workflows/iron-semi-binary-build-testing.yml @@ -0,0 +1,25 @@ +name: Iron Semi-Binary Build - testing +# description: 'Build & test that compiles the main dependencies from source.' + +on: + workflow_dispatch: + branches: + - main + pull_request: + branches: + - main + push: + branches: + - main + schedule: + # Run every morning to detect flakiness and broken dependencies + - cron: '33 1 * * *' + +jobs: + semi_binary: + uses: ./.github/workflows/reusable-industrial-ci-with-cache.yml + with: + ros_distro: iron + ros_repo: testing + upstream_workspace: ros2_robotiq_gripper.iron.repos + ref_for_scheduled_build: main diff --git a/.github/workflows/iron-source-build.yml b/.github/workflows/iron-source-build.yml new file mode 100644 index 0000000..350896d --- /dev/null +++ b/.github/workflows/iron-source-build.yml @@ -0,0 +1,19 @@ +name: Iron Source Build +on: + workflow_dispatch: + branches: + - main + push: + branches: + - main + schedule: + # Run every day to detect flakiness and broken dependencies + - cron: '03 3 * * *' + +jobs: + source: + uses: ./.github/workflows/reusable-ros-tooling-source-build.yml + with: + ros_distro: iron + ref: main + ros2_repo_branch: iron diff --git a/.github/workflows/prerelease-check.yml b/.github/workflows/prerelease-check.yml new file mode 100644 index 0000000..9052985 --- /dev/null +++ b/.github/workflows/prerelease-check.yml @@ -0,0 +1,41 @@ +name: Pre-Release Check + +on: + workflow_dispatch: + inputs: + ros_distro: + description: 'Chose ROS distribution' + required: true + default: 'rolling' + type: choice + options: + - foxy + - galactic + - humble + - iron + - rolling + branch: + description: 'Chose branch for distro' + required: true + default: 'master' + type: choice + options: + - foxy + - galactic + - humble + - iron + - master + +jobs: + pre_release: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + ref: ${{ github.event.inputs.branch }} + - name: industrial_ci + uses: ros-industrial/industrial_ci@master + env: + ROS_DISTRO: ${{ github.event.inputs.ros_distro }} + PRERELEASE: true + BASEDIR: ${{ github.workspace }}/.work diff --git a/.github/workflows/reusable-industrial-ci-with-cache.yml b/.github/workflows/reusable-industrial-ci-with-cache.yml new file mode 100644 index 0000000..490b680 --- /dev/null +++ b/.github/workflows/reusable-industrial-ci-with-cache.yml @@ -0,0 +1,96 @@ +name: Reusable industrial_ci Workflow with Cache +# Reusable action to simplify dealing with ROS/ROS2 industrial_ci builds with cache +# author: Denis Štogl + +on: + workflow_call: + inputs: + ref_for_scheduled_build: + description: 'Reference on which the repo should be checkout for scheduled build. Usually is this name of a branch or a tag.' + default: '' + required: false + type: string + + upstream_workspace: + description: 'UPSTREAM_WORKSPACE variable for industrial_ci. Usually path to local .repos file.' + required: true + type: string + ros_distro: + description: 'ROS_DISTRO variable for industrial_ci' + required: true + type: string + ros_repo: + description: 'ROS_REPO to run for industrial_ci. Possible values: "main", "testing"' + default: 'main' + required: false + type: string + os_code_name: + description: 'OS_CODE_NAME variable for industrial_ci' + default: '' + required: false + type: string + before_install_upstream_dependencies: + description: 'BEFORE_INSTALL_UPSTREAM_DEPENDENCIES variable for industrial_ci' + default: '' + required: false + type: string + + ccache_dir: + description: 'Local path to store cache (from "github.workspace"). For standard industrial_ci configuration do not have to be changed' + default: '.ccache' + required: false + type: string + basedir: + description: 'Local path to workspace base directory to cache (from "github.workspace"). For standard industrial_ci configuration do not have to be changed' + default: '.work' + required: false + type: string + + +jobs: + reusable_industrial_ci_with_cache: + name: ${{ inputs.ros_distro }} ${{ inputs.ros_repo }} ${{ inputs.os_code_name }} + runs-on: ubuntu-latest + env: + CCACHE_DIR: ${{ github.workspace }}/${{ inputs.ccache_dir }} + BASEDIR: ${{ github.workspace }}/${{ inputs.basedir }} + CACHE_PREFIX: ${{ inputs.ros_distro }}-${{ inputs.upstream_workspace }}-${{ inputs.ros_repo }}-${{ github.job }} + steps: + - name: Checkout ${{ inputs.ref }} when build is not scheduled + if: ${{ github.event_name != 'schedule' }} + uses: actions/checkout@v3 + - name: Checkout ${{ inputs.ref }} on scheduled build + if: ${{ github.event_name == 'schedule' }} + uses: actions/checkout@v3 + with: + ref: ${{ inputs.ref_for_scheduled_build }} + - name: cache target_ws + if: ${{ ! matrix.env.CCOV }} + uses: pat-s/always-upload-cache@v2.1.5 + with: + path: ${{ env.BASEDIR }}/target_ws + key: target_ws-${{ env.CACHE_PREFIX }}-${{ hashFiles('**/CMakeLists.txt', '**/package.xml') }}-${{ github.run_id }} + restore-keys: | + target_ws-${{ env.CACHE_PREFIX }}-${{ hashFiles('**/CMakeLists.txt', '**/package.xml') }} + - name: cache ccache + uses: pat-s/always-upload-cache@v2.1.5 + with: + path: ${{ env.CCACHE_DIR }} + key: ccache-${{ env.CACHE_PREFIX }}-${{ github.sha }}-${{ github.run_id }} + restore-keys: | + ccache-${{ env.CACHE_PREFIX }}-${{ github.sha }} + ccache-${{ env.CACHE_PREFIX }} + - uses: 'ros-industrial/industrial_ci@master' + env: + UPSTREAM_WORKSPACE: ${{ inputs.upstream_workspace }} + ROS_DISTRO: ${{ inputs.ros_distro }} + ROS_REPO: ${{ inputs.ros_repo }} + OS_CODE_NAME: ${{ inputs.os_code_name }} + BEFORE_INSTALL_UPSTREAM_DEPENDENCIES: ${{ inputs.before_install_upstream_dependencies }} + - name: prepare target_ws for cache + if: ${{ always() && ! matrix.env.CCOV }} + run: | + du -sh ${{ env.BASEDIR }}/target_ws + sudo find ${{ env.BASEDIR }}/target_ws -wholename '*/test_results/*' -delete + sudo rm -rf ${{ env.BASEDIR }}/target_ws/src + du -sh ${{ env.BASEDIR }}/target_ws diff --git a/.github/workflows/reusable-ros-tooling-source-build.yml b/.github/workflows/reusable-ros-tooling-source-build.yml new file mode 100644 index 0000000..584e816 --- /dev/null +++ b/.github/workflows/reusable-ros-tooling-source-build.yml @@ -0,0 +1,51 @@ +name: Reusable industrial_ci Workflow with Cache +# Reusable action to simplify dealing with ROS/ROS2 industrial_ci builds with cache +# author: Denis Štogl + +on: + workflow_call: + inputs: + ros_distro: + description: 'ROS2 distribution name' + required: true + type: string + ref: + description: 'Reference on which the repo should be checkout. Usually is this name of a branch or a tag.' + required: true + type: string + ros2_repo_branch: + description: 'Branch in the ros2/ros2 repository from which ".repos" should be used. Possible values: master (Rolling), humble, iron, galactic, foxy.' + default: 'master' + required: false + type: string + +jobs: + reusable_ros_tooling_source_build: + name: ${{ inputs.ros_distro }} ubuntu-22.04 + runs-on: ubuntu-22.04 + strategy: + fail-fast: false + steps: + - uses: ros-tooling/setup-ros@0.3.4 + with: + required-ros-distributions: ${{ inputs.ros_distro }} + - uses: actions/checkout@v3 + with: + ref: ${{ inputs.ref }} + - uses: ros-tooling/action-ros-ci@0.2.6 + with: + target-ros2-distro: ${{ inputs.ros_distro }} + # build all packages listed in the meta package + package-name: + robotiq_driver + robotiq_controllers + robotiq_description + + vcs-repo-file-url: | + https://raw.githubusercontent.com/ros2/ros2/${{ inputs.ros2_repo_branch }}/ros2.repos + https://raw.githubusercontent.com/${{ github.repository }}/${{ github.sha }}/ros2_robotiq_gripper.${{ inputs.ros_distro }}.repos?token=${{ secrets.GITHUB_TOKEN }} + colcon-mixin-repository: https://raw.githubusercontent.com/colcon/colcon-mixin-repository/master/index.yaml + - uses: actions/upload-artifact@v1 + with: + name: colcon-logs-ubuntu-22.04 + path: ros_ws/log diff --git a/.github/workflows/rolling-binary-build-main.yml b/.github/workflows/rolling-binary-build-main.yml new file mode 100644 index 0000000..a595a3f --- /dev/null +++ b/.github/workflows/rolling-binary-build-main.yml @@ -0,0 +1,26 @@ +name: Rolling Binary Build - main +# author: Denis Štogl +# description: 'Build & test all dependencies from released (binary) packages.' + +on: + workflow_dispatch: + branches: + - main + pull_request: + branches: + - main + push: + branches: + - main + schedule: + # Run every morning to detect flakiness and broken dependencies + - cron: '03 1 * * *' + +jobs: + binary: + uses: ./.github/workflows/reusable-industrial-ci-with-cache.yml + with: + ros_distro: rolling + ros_repo: main + upstream_workspace: ros2_robotiq_gripper-not-released.rolling.repos + ref_for_scheduled_build: main diff --git a/.github/workflows/rolling-binary-build-testing.yml b/.github/workflows/rolling-binary-build-testing.yml new file mode 100644 index 0000000..6dde565 --- /dev/null +++ b/.github/workflows/rolling-binary-build-testing.yml @@ -0,0 +1,26 @@ +name: Rolling Binary Build - testing +# author: Denis Štogl +# description: 'Build & test all dependencies from released (binary) packages.' + +on: + workflow_dispatch: + branches: + - main + pull_request: + branches: + - main + push: + branches: + - main + schedule: + # Run every morning to detect flakiness and broken dependencies + - cron: '03 1 * * *' + +jobs: + binary: + uses: ./.github/workflows/reusable-industrial-ci-with-cache.yml + with: + ros_distro: rolling + ros_repo: testing + upstream_workspace: ros2_robotiq_gripper-not-released.rolling.repos + ref_for_scheduled_build: main diff --git a/.github/workflows/rolling-semi-binary-build-main.yml b/.github/workflows/rolling-semi-binary-build-main.yml new file mode 100644 index 0000000..cc51f94 --- /dev/null +++ b/.github/workflows/rolling-semi-binary-build-main.yml @@ -0,0 +1,25 @@ +name: Rolling Semi-Binary Build - main +# description: 'Build & test that compiles the main dependencies from source.' + +on: + workflow_dispatch: + branches: + - main + pull_request: + branches: + - main + push: + branches: + - main + schedule: + # Run every morning to detect flakiness and broken dependencies + - cron: '33 1 * * *' + +jobs: + semi_binary: + uses: ./.github/workflows/reusable-industrial-ci-with-cache.yml + with: + ros_distro: rolling + ros_repo: main + upstream_workspace: ros2_robotiq_gripper.rolling.repos + ref_for_scheduled_build: main diff --git a/.github/workflows/rolling-semi-binary-build-testing.yml b/.github/workflows/rolling-semi-binary-build-testing.yml new file mode 100644 index 0000000..185c981 --- /dev/null +++ b/.github/workflows/rolling-semi-binary-build-testing.yml @@ -0,0 +1,25 @@ +name: Rolling Semi-Binary Build - testing +# description: 'Build & test that compiles the main dependencies from source.' + +on: + workflow_dispatch: + branches: + - main + pull_request: + branches: + - main + push: + branches: + - main + schedule: + # Run every morning to detect flakiness and broken dependencies + - cron: '33 1 * * *' + +jobs: + semi_binary: + uses: ./.github/workflows/reusable-industrial-ci-with-cache.yml + with: + ros_distro: rolling + ros_repo: testing + upstream_workspace: ros2_robotiq_gripper.rolling.repos + ref_for_scheduled_build: main diff --git a/.github/workflows/rolling-source-build.yml b/.github/workflows/rolling-source-build.yml new file mode 100644 index 0000000..6306dc6 --- /dev/null +++ b/.github/workflows/rolling-source-build.yml @@ -0,0 +1,19 @@ +name: Rolling Source Build +on: + workflow_dispatch: + branches: + - main + push: + branches: + - main + schedule: + # Run every day to detect flakiness and broken dependencies + - cron: '03 3 * * *' + +jobs: + source: + uses: ./.github/workflows/reusable-ros-tooling-source-build.yml + with: + ros_distro: rolling + ref: main + ros2_repo_branch: rolling diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f8ce1d0..c63eae3 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -14,7 +14,7 @@ repos: # Standard hooks - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v3.4.0 + rev: v4.4.0 hooks: - id: check-added-large-files exclude: \.(stl|dae)$ @@ -32,19 +32,25 @@ repos: - id: fix-byte-order-marker - repo: https://github.com/psf/black - rev: 22.3.0 + rev: 23.3.0 hooks: - id: black + - repo: https://github.com/pycqa/flake8 + rev: 5.0.4 + hooks: + - id: flake8 + # configured in .flake8 file + - repo: https://github.com/codespell-project/codespell - rev: v2.0.0 + rev: v2.2.5 hooks: - id: codespell args: ['--write-changes', '-L', 'atleast'] # Provide a comma-separated list of misspelled words that codespell should ignore (for example: '-L', 'word1,word2,word3'). exclude: \.(svg|pyc|stl|dae|lock)$ - repo: https://github.com/pre-commit/mirrors-clang-format - rev: v14.0.6 + rev: v16.0.6 hooks: - id: clang-format files: \.(c|cc|cxx|cpp|frag|glsl|h|hpp|hxx|ih|ispc|ipp|java|m|proto|vert)$ diff --git a/README.md b/README.md index b38c769..0f74c7a 100644 --- a/README.md +++ b/README.md @@ -1 +1,39 @@ # ros2_robotiq_gripper + +This repository contains the ROS 2 driver, controller and description packages for working with a Robotiq Gripper. + + +## Build status + + + +ROS2 Distro | Branch | Build status | Documentation | Released packages +:---------: | :----: | :----------: | :-----------: | :---------------: +**Rolling** | [`rolling`](https://github.com/PickNikRobotics/ros2_robotiq_gripper/tree/rolling) | [![Rolling Binary Build](https://github.com/PickNikRobotics/ros2_robotiq_gripper/actions/workflows/rolling-binary-build-main.yml/badge.svg?branch=main)](https://github.com/PickNikRobotics/ros2_robotiq_gripper/actions/workflows/rolling-binary-build-main.yml?branch=main)
[![Rolling Semi-Binary Build](https://github.com/PickNikRobotics/ros2_robotiq_gripper/actions/workflows/rolling-semi-binary-build-main.yml/badge.svg?branch=main)](https://github.com/PickNikRobotics/ros2_robotiq_gripper/actions/workflows/rolling-semi-binary-build-main.yml?branch=main) | [![Doxygen Doc Deployment](https://github.com/PickNikRobotics/ros2_robotiq_gripper/actions/workflows/doxygen-deploy.yml/badge.svg)](https://github.com/PickNikRobotics/ros2_robotiq_gripper/actions/workflows/doxygen-deploy.yml)
[Generated Doc](https://PickNikRobotics.github.io/ros2_robotiq_gripper_Documentation/rolling/html/index.html) | [ros2_robotiq_gripper](https://index.ros.org/p/ros2_robotiq_gripper/#rolling) + + +ROS2 Distro | Branch | Build status | Documentation | Released packages +:---------: | :----: | :----------: | :-----------: | :---------------: +**Humble** | [`humble`](https://github.com/PickNikRobotics/ros2_robotiq_gripper/tree/humble) | [![Humble Binary Build](https://github.com/PickNikRobotics/ros2_robotiq_gripper/actions/workflows/humble-binary-build-main.yml/badge.svg?branch=main)](https://github.com/PickNikRobotics/ros2_robotiq_gripper/actions/workflows/humble-binary-build-main.yml?branch=main)
[![Humble Semi-Binary Build](https://github.com/PickNikRobotics/ros2_robotiq_gripper/actions/workflows/humble-semi-binary-build-main.yml/badge.svg?branch=main)](https://github.com/PickNikRobotics/ros2_robotiq_gripper/actions/workflows/humble-semi-binary-build-main.yml?branch=main) | [![Doxygen Doc Deployment](https://github.com/PickNikRobotics/ros2_robotiq_gripper/actions/workflows/doxygen-deploy.yml/badge.svg)](https://github.com/PickNikRobotics/ros2_robotiq_gripper/actions/workflows/doxygen-deploy.yml)
[Generated Doc](https://PickNikRobotics.github.io/ros2_robotiq_gripper_Documentation/humble/html/index.html) | [ros2_robotiq_gripper](https://index.ros.org/p/ros2_robotiq_gripper/#humble) + + +ROS2 Distro | Branch | Build status | Documentation | Released packages +:---------: | :----: | :----------: | :-----------: | :---------------: +**Iron** | [`iron`](https://github.com/PickNikRobotics/ros2_robotiq_gripper/tree/iron) | [![Iron Binary Build](https://github.com/PickNikRobotics/ros2_robotiq_gripper/actions/workflows/iron-binary-build-main.yml/badge.svg?branch=main)](https://github.com/PickNikRobotics/ros2_robotiq_gripper/actions/workflows/iron-binary-build-main.yml?branch=main)
[![Iron Semi-Binary Build](https://github.com/PickNikRobotics/ros2_robotiq_gripper/actions/workflows/iron-semi-binary-build-main.yml/badge.svg?branch=main)](https://github.com/PickNikRobotics/ros2_robotiq_gripper/actions/workflows/iron-semi-binary-build-main.yml?branch=main) | [![Doxygen Doc Deployment](https://github.com/PickNikRobotics/ros2_robotiq_gripper/actions/workflows/doxygen-deploy.yml/badge.svg)](https://github.com/PickNikRobotics/ros2_robotiq_gripper/actions/workflows/doxygen-deploy.yml)
[Generated Doc](https://PickNikRobotics.github.io/ros2_robotiq_gripper_Documentation/iron/html/index.html) | [ros2_robotiq_gripper](https://index.ros.org/p/ros2_robotiq_gripper/#iron) + +### Explanation of different build types + +**NOTE**: There are three build stages checking current and future compatibility of the package. + +[Detailed build status](.github/workflows/README.md) + +1. Binary builds - against released packages (main and testing) in ROS distributions. Shows that direct local build is possible. + + Uses repos file: `$NAME$-not-released..repos` + +1. Semi-binary builds - against released core ROS packages (main and testing), but the immediate dependencies are pulled from source. + Shows that local build with dependencies is possible and if fails there we can expect that after the next package sync we will not be able to build. + + Uses repos file: `$NAME$.repos` + +1. Source build - also core ROS packages are build from source. It shows potential issues in the mid future. diff --git a/robotiq_controllers/CMakeLists.txt b/robotiq_controllers/CMakeLists.txt index 57fa910..5e955f0 100644 --- a/robotiq_controllers/CMakeLists.txt +++ b/robotiq_controllers/CMakeLists.txt @@ -55,6 +55,11 @@ if(BUILD_TESTING) # comment the line when this package is in a git repo and when # a copyright and license is added to all source files set(ament_cmake_cpplint_FOUND TRUE) + + # the following skips uncrustify + # ament_uncrustify and ament_clang_format cannot both be satisfied + set(ament_cmake_uncrustify_FOUND TRUE) + ament_lint_auto_find_test_dependencies() endif() diff --git a/robotiq_controllers/include/robotiq_controllers/robotiq_activation_controller.hpp b/robotiq_controllers/include/robotiq_controllers/robotiq_activation_controller.hpp index 20126ea..f922400 100644 --- a/robotiq_controllers/include/robotiq_controllers/robotiq_activation_controller.hpp +++ b/robotiq_controllers/include/robotiq_controllers/robotiq_activation_controller.hpp @@ -29,7 +29,6 @@ #pragma once #include "controller_interface/controller_interface.hpp" - #include "std_srvs/srv/trigger.hpp" namespace robotiq_controllers @@ -41,17 +40,19 @@ class RobotiqActivationController : public controller_interface::ControllerInter controller_interface::InterfaceConfiguration state_interface_configuration() const override; - controller_interface::return_type update(const rclcpp::Time& time, const rclcpp::Duration& period) override; + controller_interface::return_type update( + const rclcpp::Time & time, const rclcpp::Duration & period) override; - CallbackReturn on_activate(const rclcpp_lifecycle::State& previous_state) override; + CallbackReturn on_activate(const rclcpp_lifecycle::State & previous_state) override; - CallbackReturn on_deactivate(const rclcpp_lifecycle::State& previous_state) override; + CallbackReturn on_deactivate(const rclcpp_lifecycle::State & previous_state) override; CallbackReturn on_init() override; private: - bool reactivateGripper(std_srvs::srv::Trigger::Request::SharedPtr req, - std_srvs::srv::Trigger::Response::SharedPtr resp); + bool reactivateGripper( + std_srvs::srv::Trigger::Request::SharedPtr req, + std_srvs::srv::Trigger::Response::SharedPtr resp); static constexpr double ASYNC_WAITING = 2.0; enum CommandInterfaces diff --git a/robotiq_controllers/package.xml b/robotiq_controllers/package.xml index 51d9170..56525ad 100644 --- a/robotiq_controllers/package.xml +++ b/robotiq_controllers/package.xml @@ -4,10 +4,10 @@ robotiq_controllers 0.0.0 Controllers for the Robotiq gripper. - Cory Crean Alex Moriarty Marq Rasumessen BSD-3-Clause + Cory Crean ament_cmake diff --git a/robotiq_controllers/src/robotiq_activation_controller.cpp b/robotiq_controllers/src/robotiq_activation_controller.cpp index aa63d21..03c4fa8 100644 --- a/robotiq_controllers/src/robotiq_activation_controller.cpp +++ b/robotiq_controllers/src/robotiq_activation_controller.cpp @@ -30,7 +30,8 @@ namespace robotiq_controllers { -controller_interface::InterfaceConfiguration RobotiqActivationController::command_interface_configuration() const +controller_interface::InterfaceConfiguration +RobotiqActivationController::command_interface_configuration() const { controller_interface::InterfaceConfiguration config; config.type = controller_interface::interface_configuration_type::INDIVIDUAL; @@ -41,7 +42,8 @@ controller_interface::InterfaceConfiguration RobotiqActivationController::comman return config; } -controller_interface::InterfaceConfiguration RobotiqActivationController::state_interface_configuration() const +controller_interface::InterfaceConfiguration +RobotiqActivationController::state_interface_configuration() const { controller_interface::InterfaceConfiguration config; config.type = controller_interface::interface_configuration_type::INDIVIDUAL; @@ -49,67 +51,62 @@ controller_interface::InterfaceConfiguration RobotiqActivationController::state_ return config; } -controller_interface::return_type RobotiqActivationController::update(const rclcpp::Time& /*time*/, - const rclcpp::Duration& /*period*/) +controller_interface::return_type RobotiqActivationController::update( + const rclcpp::Time & /*time*/, const rclcpp::Duration & /*period*/) { return controller_interface::return_type::OK; } rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn -RobotiqActivationController::on_activate(const rclcpp_lifecycle::State& /*previous_state*/) +RobotiqActivationController::on_activate(const rclcpp_lifecycle::State & /*previous_state*/) { // Check command interfaces. - if (command_interfaces_.size() != 2) - { - RCLCPP_ERROR(get_node()->get_logger(), "Expected %d command interfaces, but got %zu.", 2, - command_interfaces_.size()); + if (command_interfaces_.size() != 2) { + RCLCPP_ERROR( + get_node()->get_logger(), "Expected %d command interfaces, but got %zu.", 2, + command_interfaces_.size()); return rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn::ERROR; } - try - { + try { // Create service for re-activating the gripper. reactivate_gripper_srv_ = get_node()->create_service( - "~/reactivate_gripper", - [this](std_srvs::srv::Trigger::Request::SharedPtr req, std_srvs::srv::Trigger::Response::SharedPtr resp) { - this->reactivateGripper(req, resp); - }); - } - catch (...) - { + "~/reactivate_gripper", + [this]( + std_srvs::srv::Trigger::Request::SharedPtr req, + std_srvs::srv::Trigger::Response::SharedPtr resp) { this->reactivateGripper(req, resp); }); + } catch (...) { return LifecycleNodeInterface::CallbackReturn::ERROR; } return LifecycleNodeInterface::CallbackReturn::SUCCESS; } rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn -RobotiqActivationController::on_deactivate(const rclcpp_lifecycle::State& /*previous_state*/) +RobotiqActivationController::on_deactivate(const rclcpp_lifecycle::State & /*previous_state*/) { - try - { + try { reactivate_gripper_srv_.reset(); - } - catch (...) - { + } catch (...) { return LifecycleNodeInterface::CallbackReturn::ERROR; } return LifecycleNodeInterface::CallbackReturn::SUCCESS; } -rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn RobotiqActivationController::on_init() +rclcpp_lifecycle::node_interfaces::LifecycleNodeInterface::CallbackReturn +RobotiqActivationController::on_init() { return LifecycleNodeInterface::CallbackReturn::SUCCESS; } -bool RobotiqActivationController::reactivateGripper(std_srvs::srv::Trigger::Request::SharedPtr /*req*/, - std_srvs::srv::Trigger::Response::SharedPtr resp) +bool RobotiqActivationController::reactivateGripper( + std_srvs::srv::Trigger::Request::SharedPtr /*req*/, + std_srvs::srv::Trigger::Response::SharedPtr resp) { command_interfaces_[REACTIVATE_GRIPPER_RESPONSE].set_value(ASYNC_WAITING); command_interfaces_[REACTIVATE_GRIPPER_CMD].set_value(1.0); - while (command_interfaces_[REACTIVATE_GRIPPER_RESPONSE].get_value() == ASYNC_WAITING) - { + while (command_interfaces_[REACTIVATE_GRIPPER_RESPONSE].get_value() == ASYNC_WAITING) { std::this_thread::sleep_for(std::chrono::milliseconds(50)); } resp->success = command_interfaces_[REACTIVATE_GRIPPER_RESPONSE].get_value(); @@ -120,4 +117,5 @@ bool RobotiqActivationController::reactivateGripper(std_srvs::srv::Trigger::Requ #include "pluginlib/class_list_macros.hpp" -PLUGINLIB_EXPORT_CLASS(robotiq_controllers::RobotiqActivationController, controller_interface::ControllerInterface) +PLUGINLIB_EXPORT_CLASS( + robotiq_controllers::RobotiqActivationController, controller_interface::ControllerInterface) diff --git a/robotiq_description/launch/view_gripper.launch.py b/robotiq_description/launch/view_gripper.launch.py index 6fc9038..776ddd9 100644 --- a/robotiq_description/launch/view_gripper.launch.py +++ b/robotiq_description/launch/view_gripper.launch.py @@ -41,7 +41,9 @@ def generate_launch_description(): pkg_share = launch_ros.substitutions.FindPackageShare( package="robotiq_description" ).find("robotiq_description") - default_model_path = os.path.join(pkg_share, "urdf", "robotiq_2f_85_gripper.urdf.xacro") + default_model_path = os.path.join( + pkg_share, "urdf", "robotiq_2f_85_gripper.urdf.xacro" + ) default_rviz_config_path = os.path.join(pkg_share, "rviz", "view_urdf.rviz") args = [] diff --git a/robotiq_driver/CMakeLists.txt b/robotiq_driver/CMakeLists.txt index b89d558..bda81ea 100644 --- a/robotiq_driver/CMakeLists.txt +++ b/robotiq_driver/CMakeLists.txt @@ -83,6 +83,13 @@ if(BUILD_TESTING) # comment the line when this package is in a git repo and when # a copyright and license is added to all source files set(ament_cmake_cpplint_FOUND TRUE) + # the following skips uncrustify + # ament_uncrustify and ament_clang_format cannot both be satisfied + set(ament_cmake_uncrustify_FOUND TRUE) + # the following skips ament_flake8 + # ament_flake8 and black fight over double or single quotes + # flake8 is run via pre-commit with a .flake8 configuration file + set(ament_cmake_flake8_FOUND TRUE) ament_lint_auto_find_test_dependencies() endif() diff --git a/robotiq_driver/include/robotiq_driver/crc.hpp b/robotiq_driver/include/robotiq_driver/crc.hpp index 45b0507..ca19d21 100644 --- a/robotiq_driver/include/robotiq_driver/crc.hpp +++ b/robotiq_driver/include/robotiq_driver/crc.hpp @@ -1,6 +1,34 @@ +// Copyright (c) 2022 PickNik, Inc. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// * Neither the name of the {copyright_holder} nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + #pragma once -#include #include +#include -uint16_t computeCRC(const std::vector& cmd); +uint16_t computeCRC(const std::vector & cmd); diff --git a/robotiq_driver/include/robotiq_driver/hardware_interface.hpp b/robotiq_driver/include/robotiq_driver/hardware_interface.hpp index 5f52b75..06fd8e3 100644 --- a/robotiq_driver/include/robotiq_driver/hardware_interface.hpp +++ b/robotiq_driver/include/robotiq_driver/hardware_interface.hpp @@ -29,6 +29,7 @@ #pragma once #include +#include #include #include #include @@ -39,9 +40,8 @@ #include "hardware_interface/types/hardware_interface_return_values.hpp" #include "rclcpp/macros.hpp" #include "rclcpp/rclcpp.hpp" - -#include "robotiq_driver/visibility_control.h" #include "robotiq_driver/robotiq_gripper_interface.hpp" +#include "robotiq_driver/visibility_control.h" namespace robotiq_driver { @@ -54,7 +54,7 @@ class RobotiqGripperHardwareInterface : public hardware_interface::SystemInterfa RobotiqGripperHardwareInterface(); ROBOTIQ_DRIVER_PUBLIC - CallbackReturn on_init(const hardware_interface::HardwareInfo& info) override; + CallbackReturn on_init(const hardware_interface::HardwareInfo & info) override; ROBOTIQ_DRIVER_PUBLIC std::vector export_state_interfaces() override; @@ -63,16 +63,18 @@ class RobotiqGripperHardwareInterface : public hardware_interface::SystemInterfa std::vector export_command_interfaces() override; ROBOTIQ_DRIVER_PUBLIC - CallbackReturn on_activate(const rclcpp_lifecycle::State& previous_state) override; + CallbackReturn on_activate(const rclcpp_lifecycle::State & previous_state) override; ROBOTIQ_DRIVER_PUBLIC - CallbackReturn on_deactivate(const rclcpp_lifecycle::State& previous_state) override; + CallbackReturn on_deactivate(const rclcpp_lifecycle::State & previous_state) override; ROBOTIQ_DRIVER_PUBLIC - hardware_interface::return_type read(const rclcpp::Time& time, const rclcpp::Duration& period) override; + hardware_interface::return_type read( + const rclcpp::Time & time, const rclcpp::Duration & period) override; ROBOTIQ_DRIVER_PUBLIC - hardware_interface::return_type write(const rclcpp::Time& time, const rclcpp::Duration& period) override; + hardware_interface::return_type write( + const rclcpp::Time & time, const rclcpp::Duration & period) override; private: static constexpr double NO_NEW_CMD_ = std::numeric_limits::quiet_NaN(); diff --git a/robotiq_driver/include/robotiq_driver/robotiq_gripper_interface.hpp b/robotiq_driver/include/robotiq_driver/robotiq_gripper_interface.hpp index 8fef23c..c6203e2 100644 --- a/robotiq_driver/include/robotiq_driver/robotiq_gripper_interface.hpp +++ b/robotiq_driver/include/robotiq_driver/robotiq_gripper_interface.hpp @@ -28,11 +28,11 @@ #pragma once +#include + #include #include -#include - /** * @brief This class is responsible for communicating with the gripper via a serial port, and maintaining a record of * the gripper's current state. @@ -41,7 +41,8 @@ class RobotiqGripperInterface { public: - RobotiqGripperInterface(const std::string& com_port = "/dev/ttyUSB0", uint8_t slave_id = 0x09); + explicit RobotiqGripperInterface( + const std::string & com_port = "/dev/ttyUSB0", uint8_t slave_id = 0x09); /** * @brief Activates the gripper. @@ -122,7 +123,8 @@ class RobotiqGripperInterface private: std::vector createReadCommand(uint16_t first_register, uint8_t num_registers); - std::vector createWriteCommand(uint16_t first_register, const std::vector& data); + std::vector createWriteCommand( + uint16_t first_register, const std::vector & data); /** * @brief read response from the gripper. @@ -138,7 +140,7 @@ class RobotiqGripperInterface * @param cmd The command. * @throw serial::IOException on failure to successfully communicate with gripper port */ - void sendCommand(const std::vector& cmd); + void sendCommand(const std::vector & cmd); /** * @brief Read the current status of the gripper, and update member variables as appropriate. diff --git a/robotiq_driver/package.xml b/robotiq_driver/package.xml index bb0f7cf..99f3752 100644 --- a/robotiq_driver/package.xml +++ b/robotiq_driver/package.xml @@ -4,10 +4,10 @@ robotiq_driver 0.0.0 ROS2 driver package for the Robotiq gripper. - Cory Crean Alex Moriarty Marq Rasumessen BSD + Cory Crean ament_cmake diff --git a/robotiq_driver/src/crc.cpp b/robotiq_driver/src/crc.cpp index db69d3c..f6a8563 100644 --- a/robotiq_driver/src/crc.cpp +++ b/robotiq_driver/src/crc.cpp @@ -1,48 +1,77 @@ +// Copyright (c) 2022 PickNik, Inc. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// * Neither the name of the {copyright_holder} nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + #include "robotiq_driver/crc.hpp" /* Table of CRC values for high–order byte */ static unsigned char kCRCHiTable[] = { - 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, - 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, - 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, - 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, - 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, - 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, - 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, - 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, - 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, - 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, - 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, - 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, - 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, - 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 -}; + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, + 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, + 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, + 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, + 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, + 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, + 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, + 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, + 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, + 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40}; /* Table of CRC values for low–order byte */ static unsigned char kCRCLoTable[] = { - 0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, - 0xCD, 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, - 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, - 0x12, 0x13, 0xD3, 0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, - 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, - 0x38, 0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, - 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26, 0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1, 0x63, - 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE, - 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E, 0x7F, - 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5, 0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, - 0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, - 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, - 0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C, 0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, - 0x86, 0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80, 0x40 -}; + 0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, + 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8, + 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, + 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3, 0x11, 0xD1, 0xD0, 0x10, + 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, + 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, + 0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED, 0xEC, 0x2C, + 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26, 0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, + 0xA0, 0x60, 0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4, + 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68, + 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, + 0xB4, 0x74, 0x75, 0xB5, 0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0, + 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, + 0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, + 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C, + 0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80, 0x40}; -uint16_t computeCRC(const std::vector& cmd) +uint16_t computeCRC(const std::vector & cmd) { uint16_t crc_hi = 0x00FF; uint16_t crc_lo = 0x00FF; - for (auto byte : cmd) - { + for (auto byte : cmd) { std::size_t index = crc_lo ^ byte; crc_lo = crc_hi ^ kCRCHiTable[index]; crc_hi = kCRCLoTable[index]; diff --git a/robotiq_driver/src/gripper_interface_test.cpp b/robotiq_driver/src/gripper_interface_test.cpp index f28ccc9..c93a8de 100644 --- a/robotiq_driver/src/gripper_interface_test.cpp +++ b/robotiq_driver/src/gripper_interface_test.cpp @@ -29,15 +29,14 @@ #include #include -#include +#include "robotiq_driver/robotiq_gripper_interface.hpp" constexpr auto kComPort = "/dev/ttyUSB0"; constexpr auto kSlaveID = 0x09; int main() { - try - { + try { RobotiqGripperInterface gripper(kComPort, kSlaveID); std::cout << "Deactivating gripper...\n"; @@ -50,29 +49,25 @@ int main() std::cout << "Closing gripper...\n"; gripper.setGripperPosition(0xFF); - while (gripper.gripperIsMoving()) - { + while (gripper.gripperIsMoving()) { std::this_thread::sleep_for(std::chrono::milliseconds(500)); } std::cout << "Opening gripper...\n"; gripper.setGripperPosition(0x00); - while (gripper.gripperIsMoving()) - { + while (gripper.gripperIsMoving()) { std::this_thread::sleep_for(std::chrono::milliseconds(500)); } std::cout << "Half closing gripper...\n"; gripper.setGripperPosition(0x80); - while (gripper.gripperIsMoving()) - { + while (gripper.gripperIsMoving()) { std::this_thread::sleep_for(std::chrono::milliseconds(500)); } std::cout << "Opening gripper...\n"; gripper.setGripperPosition(0x00); - while (gripper.gripperIsMoving()) - { + while (gripper.gripperIsMoving()) { std::this_thread::sleep_for(std::chrono::milliseconds(500)); } @@ -81,8 +76,7 @@ int main() std::cout << "Closing gripper...\n"; gripper.setGripperPosition(0xFF); - while (gripper.gripperIsMoving()) - { + while (gripper.gripperIsMoving()) { std::this_thread::sleep_for(std::chrono::milliseconds(500)); } @@ -91,13 +85,10 @@ int main() std::cout << "Opening gripper...\n"; gripper.setGripperPosition(0x00); - while (gripper.gripperIsMoving()) - { + while (gripper.gripperIsMoving()) { std::this_thread::sleep_for(std::chrono::milliseconds(500)); } - } - catch (const serial::IOException& e) - { + } catch (const serial::IOException & e) { std::cout << "Failed to communicating with the Gripper. Please check the Gripper connection"; return 1; } diff --git a/robotiq_driver/src/hardware_interface.cpp b/robotiq_driver/src/hardware_interface.cpp index 60baa70..0f9aa8b 100644 --- a/robotiq_driver/src/hardware_interface.cpp +++ b/robotiq_driver/src/hardware_interface.cpp @@ -28,6 +28,8 @@ #include "robotiq_driver/hardware_interface.hpp" +#include + #include #include #include @@ -37,7 +39,6 @@ #include "hardware_interface/actuator_interface.hpp" #include "hardware_interface/types/hardware_interface_type_values.hpp" #include "rclcpp/rclcpp.hpp" -#include constexpr uint8_t kGripperMinPos = 3; constexpr uint8_t kGripperMaxPos = 230; @@ -47,14 +48,12 @@ const auto kLogger = rclcpp::get_logger("RobotiqGripperHardwareInterface"); namespace robotiq_driver { -RobotiqGripperHardwareInterface::RobotiqGripperHardwareInterface() -{ -} +RobotiqGripperHardwareInterface::RobotiqGripperHardwareInterface() {} -hardware_interface::CallbackReturn RobotiqGripperHardwareInterface::on_init(const hardware_interface::HardwareInfo& info) +hardware_interface::CallbackReturn RobotiqGripperHardwareInterface::on_init( + const hardware_interface::HardwareInfo & info) { - if (hardware_interface::SystemInterface::on_init(info) != CallbackReturn::SUCCESS) - { + if (hardware_interface::SystemInterface::on_init(info) != CallbackReturn::SUCCESS) { return CallbackReturn::ERROR; } @@ -74,52 +73,48 @@ hardware_interface::CallbackReturn RobotiqGripperHardwareInterface::on_init(cons reactivate_gripper_cmd_ = NO_NEW_CMD_; reactivate_gripper_async_cmd_.store(false); - const hardware_interface::ComponentInfo& joint = info_.joints[0]; + const hardware_interface::ComponentInfo & joint = info_.joints[0]; // There is one command interface: position. - if (joint.command_interfaces.size() != 1) - { - RCLCPP_FATAL(kLogger, "Joint '%s' has %zu command interfaces found. 1 expected.", joint.name.c_str(), - joint.command_interfaces.size()); + if (joint.command_interfaces.size() != 1) { + RCLCPP_FATAL( + kLogger, "Joint '%s' has %zu command interfaces found. 1 expected.", joint.name.c_str(), + joint.command_interfaces.size()); return CallbackReturn::ERROR; } - if (joint.command_interfaces[0].name != hardware_interface::HW_IF_POSITION) - { - RCLCPP_FATAL(kLogger, "Joint '%s' has %s command interfaces found. '%s' expected.", joint.name.c_str(), - joint.command_interfaces[0].name.c_str(), hardware_interface::HW_IF_POSITION); + if (joint.command_interfaces[0].name != hardware_interface::HW_IF_POSITION) { + RCLCPP_FATAL( + kLogger, "Joint '%s' has %s command interfaces found. '%s' expected.", joint.name.c_str(), + joint.command_interfaces[0].name.c_str(), hardware_interface::HW_IF_POSITION); return CallbackReturn::ERROR; } // There are two state interfaces: position and velocity. - if (joint.state_interfaces.size() != 2) - { - RCLCPP_FATAL(kLogger, "Joint '%s' has %zu state interface. 2 expected.", joint.name.c_str(), - joint.state_interfaces.size()); + if (joint.state_interfaces.size() != 2) { + RCLCPP_FATAL( + kLogger, "Joint '%s' has %zu state interface. 2 expected.", joint.name.c_str(), + joint.state_interfaces.size()); return CallbackReturn::ERROR; } - for (int i = 0; i < 2; ++i) - { + for (int i = 0; i < 2; ++i) { if (!(joint.state_interfaces[i].name == hardware_interface::HW_IF_POSITION || - joint.state_interfaces[i].name == hardware_interface::HW_IF_VELOCITY)) - { - RCLCPP_FATAL(kLogger, "Joint '%s' has %s state interface. Expected %s or %s.", joint.name.c_str(), - joint.state_interfaces[i].name.c_str(), hardware_interface::HW_IF_POSITION, - hardware_interface::HW_IF_VELOCITY); + joint.state_interfaces[i].name == hardware_interface::HW_IF_VELOCITY)) { + RCLCPP_FATAL( + kLogger, "Joint '%s' has %s state interface. Expected %s or %s.", joint.name.c_str(), + joint.state_interfaces[i].name.c_str(), hardware_interface::HW_IF_POSITION, + hardware_interface::HW_IF_VELOCITY); return CallbackReturn::ERROR; } } - try - { + try { // Create the interface to the gripper. gripper_interface_ = std::make_unique(com_port_); gripper_interface_->setSpeed(gripper_speed * 0xFF); gripper_interface_->setForce(gripper_force * 0xFF); - } - catch (const serial::IOException& e) - { + } catch (const serial::IOException & e) { RCLCPP_FATAL(kLogger, "Failed to open gripper port."); return CallbackReturn::ERROR; } @@ -127,51 +122,49 @@ hardware_interface::CallbackReturn RobotiqGripperHardwareInterface::on_init(cons return CallbackReturn::SUCCESS; } -std::vector RobotiqGripperHardwareInterface::export_state_interfaces() +std::vector +RobotiqGripperHardwareInterface::export_state_interfaces() { std::vector state_interfaces; - state_interfaces.emplace_back( - hardware_interface::StateInterface(info_.joints[0].name, hardware_interface::HW_IF_POSITION, &gripper_position_)); - state_interfaces.emplace_back( - hardware_interface::StateInterface(info_.joints[0].name, hardware_interface::HW_IF_VELOCITY, &gripper_velocity_)); + state_interfaces.emplace_back(hardware_interface::StateInterface( + info_.joints[0].name, hardware_interface::HW_IF_POSITION, &gripper_position_)); + state_interfaces.emplace_back(hardware_interface::StateInterface( + info_.joints[0].name, hardware_interface::HW_IF_VELOCITY, &gripper_velocity_)); return state_interfaces; } -std::vector RobotiqGripperHardwareInterface::export_command_interfaces() +std::vector +RobotiqGripperHardwareInterface::export_command_interfaces() { std::vector command_interfaces; command_interfaces.emplace_back(hardware_interface::CommandInterface( - info_.joints[0].name, hardware_interface::HW_IF_POSITION, &gripper_position_command_)); - command_interfaces.emplace_back( - hardware_interface::CommandInterface("reactivate_gripper", "reactivate_gripper_cmd", &reactivate_gripper_cmd_)); + info_.joints[0].name, hardware_interface::HW_IF_POSITION, &gripper_position_command_)); + command_interfaces.emplace_back(hardware_interface::CommandInterface( + "reactivate_gripper", "reactivate_gripper_cmd", &reactivate_gripper_cmd_)); command_interfaces.emplace_back(hardware_interface::CommandInterface( - "reactivate_gripper", "reactivate_gripper_response", &reactivate_gripper_response_)); + "reactivate_gripper", "reactivate_gripper_response", &reactivate_gripper_response_)); return command_interfaces; } -hardware_interface::CallbackReturn -RobotiqGripperHardwareInterface::on_activate(const rclcpp_lifecycle::State& /*previous_state*/) +hardware_interface::CallbackReturn RobotiqGripperHardwareInterface::on_activate( + const rclcpp_lifecycle::State & /*previous_state*/) { // set some default values for joints - if (std::isnan(gripper_position_)) - { + if (std::isnan(gripper_position_)) { gripper_position_ = 0; gripper_velocity_ = 0; gripper_position_command_ = 0; } // Activate the gripper. - try - { + try { gripper_interface_->deactivateGripper(); gripper_interface_->activateGripper(); - } - catch (const serial::IOException& e) - { + } catch (const serial::IOException & e) { RCLCPP_FATAL(kLogger, "Failed to communicate with Gripper. Check Gripper connection."); return CallbackReturn::ERROR; } @@ -185,16 +178,13 @@ RobotiqGripperHardwareInterface::on_activate(const rclcpp_lifecycle::State& /*pr const auto io_interval = std::chrono::milliseconds(10); auto last_io = std::chrono::high_resolution_clock::now(); - while (command_interface_is_running_.load()) - { + while (command_interface_is_running_.load()) { const auto now = std::chrono::high_resolution_clock::now(); - if (now - last_io > io_interval) - { - try - { - // Re-activate the gripper (this can be used, for example, to re-run the auto-calibration). - if (reactivate_gripper_async_cmd_.load()) - { + if (now - last_io > io_interval) { + try { + // Re-activate the gripper + // (this can be used, for example, to re-run the auto-calibration). + if (reactivate_gripper_async_cmd_.load()) { this->gripper_interface_->deactivateGripper(); this->gripper_interface_->activateGripper(); reactivate_gripper_async_cmd_.store(false); @@ -208,10 +198,9 @@ RobotiqGripperHardwareInterface::on_activate(const rclcpp_lifecycle::State& /*pr gripper_current_state_.store(this->gripper_interface_->getGripperPosition()); last_io = now; - } - catch (serial::IOException& e) - { - RCLCPP_ERROR(kLogger, "Check Robotiq Gripper connection and restart drivers. ERROR: %s", e.what()); + } catch (serial::IOException & e) { + RCLCPP_ERROR( + kLogger, "Check Robotiq Gripper connection and restart drivers. ERROR: %s", e.what()); command_interface_is_running_.store(false); } } @@ -221,18 +210,15 @@ RobotiqGripperHardwareInterface::on_activate(const rclcpp_lifecycle::State& /*pr return CallbackReturn::SUCCESS; } -hardware_interface::CallbackReturn -RobotiqGripperHardwareInterface::on_deactivate(const rclcpp_lifecycle::State& /*previous_state*/) +hardware_interface::CallbackReturn RobotiqGripperHardwareInterface::on_deactivate( + const rclcpp_lifecycle::State & /*previous_state*/) { command_interface_is_running_.store(false); command_interface_.join(); - try - { + try { gripper_interface_->deactivateGripper(); - } - catch (const std::exception& e) - { + } catch (const std::exception & e) { RCLCPP_ERROR(kLogger, "Failed to deactivate gripper. Check Gripper connection"); return CallbackReturn::ERROR; } @@ -240,20 +226,19 @@ RobotiqGripperHardwareInterface::on_deactivate(const rclcpp_lifecycle::State& /* return CallbackReturn::SUCCESS; } -hardware_interface::return_type RobotiqGripperHardwareInterface::read(const rclcpp::Time& /*time*/, - const rclcpp::Duration& /*period*/) +hardware_interface::return_type RobotiqGripperHardwareInterface::read( + const rclcpp::Time & /*time*/, const rclcpp::Duration & /*period*/) { - gripper_position_ = gripper_closed_pos_ * (gripper_current_state_.load() - kGripperMinPos) / kGripperRange; + gripper_position_ = + gripper_closed_pos_ * (gripper_current_state_.load() - kGripperMinPos) / kGripperRange; - if (!std::isnan(reactivate_gripper_cmd_)) - { + if (!std::isnan(reactivate_gripper_cmd_)) { RCLCPP_INFO(kLogger, "Sending gripper reactivation request."); reactivate_gripper_async_cmd_.store(true); reactivate_gripper_cmd_ = NO_NEW_CMD_; } - if (reactivate_gripper_async_response_.load().has_value()) - { + if (reactivate_gripper_async_response_.load().has_value()) { reactivate_gripper_response_ = reactivate_gripper_async_response_.load().value(); reactivate_gripper_async_response_.store(std::nullopt); } @@ -261,10 +246,11 @@ hardware_interface::return_type RobotiqGripperHardwareInterface::read(const rclc return hardware_interface::return_type::OK; } -hardware_interface::return_type RobotiqGripperHardwareInterface::write(const rclcpp::Time& /*time*/, - const rclcpp::Duration& /*period*/) +hardware_interface::return_type RobotiqGripperHardwareInterface::write( + const rclcpp::Time & /*time*/, const rclcpp::Duration & /*period*/) { - double gripper_pos = (gripper_position_command_ / gripper_closed_pos_) * kGripperRange + kGripperMinPos; + double gripper_pos = + (gripper_position_command_ / gripper_closed_pos_) * kGripperRange + kGripperMinPos; gripper_pos = std::max(std::min(gripper_pos, 255.0), 0.0); write_command_.store(uint8_t(gripper_pos)); @@ -275,4 +261,5 @@ hardware_interface::return_type RobotiqGripperHardwareInterface::write(const rcl #include "pluginlib/class_list_macros.hpp" -PLUGINLIB_EXPORT_CLASS(robotiq_driver::RobotiqGripperHardwareInterface, hardware_interface::SystemInterface) +PLUGINLIB_EXPORT_CLASS( + robotiq_driver::RobotiqGripperHardwareInterface, hardware_interface::SystemInterface) diff --git a/robotiq_driver/src/robotiq_gripper_interface.cpp b/robotiq_driver/src/robotiq_gripper_interface.cpp index ab26df8..58b6d24 100644 --- a/robotiq_driver/src/robotiq_gripper_interface.cpp +++ b/robotiq_driver/src/robotiq_gripper_interface.cpp @@ -27,12 +27,13 @@ // POSSIBILITY OF SUCH DAMAGE. #include "robotiq_driver/robotiq_gripper_interface.hpp" -#include "robotiq_driver/crc.hpp" +#include #include #include #include -#include + +#include "robotiq_driver/crc.hpp" constexpr int kBaudRate = 115200; constexpr auto kTimeoutMilliseconds = 1000; @@ -62,55 +63,44 @@ constexpr size_t kResponseHeaderSize = 3; constexpr size_t kGripperStatusIndex = 0; constexpr size_t kPositionIndex = 4; -static uint8_t getFirstByte(uint16_t val) -{ - return (val & 0xFF00) >> 8; -} +static uint8_t getFirstByte(uint16_t val) { return (val & 0xFF00) >> 8; } -static uint8_t getSecondByte(uint16_t val) -{ - return val & 0x00FF; -} +static uint8_t getSecondByte(uint16_t val) { return val & 0x00FF; } -RobotiqGripperInterface::RobotiqGripperInterface(const std::string& com_port, uint8_t slave_id) - : port_(com_port, kBaudRate, serial::Timeout::simpleTimeout(kTimeoutMilliseconds)) - , slave_id_(slave_id) - , read_command_(createReadCommand(kFirstOutputRegister, kNumOutputRegisters)) - , commanded_gripper_speed_(0x80) - , commanded_gripper_force_(0x80) +RobotiqGripperInterface::RobotiqGripperInterface(const std::string & com_port, uint8_t slave_id) +: port_(com_port, kBaudRate, serial::Timeout::simpleTimeout(kTimeoutMilliseconds)), + slave_id_(slave_id), + read_command_(createReadCommand(kFirstOutputRegister, kNumOutputRegisters)), + commanded_gripper_speed_(0x80), + commanded_gripper_force_(0x80) { - if (!port_.isOpen()) - { + if (!port_.isOpen()) { THROW(serial::IOException, "Failed to open gripper port."); } } void RobotiqGripperInterface::activateGripper() { - const auto cmd = createWriteCommand(kActionRequestRegister, { 0x0100, 0x0000, 0x0000 } // set rACT to 1, clear all - // other registers. + const auto cmd = createWriteCommand( + kActionRequestRegister, {0x0100, 0x0000, 0x0000} // set rACT to 1, clear all + // other registers. ); - try - { + try { sendCommand(cmd); readResponse(kWriteResponseSize); updateStatus(); - if (gripper_status_ == GripperStatus::COMPLETED) - { + if (gripper_status_ == GripperStatus::COMPLETED) { return; } - while (gripper_status_ == GripperStatus::IN_PROGRESS) - { + while (gripper_status_ == GripperStatus::IN_PROGRESS) { std::this_thread::sleep_for(std::chrono::milliseconds(1000)); updateStatus(); } - } - catch (const serial::IOException& e) - { + } catch (const serial::IOException & e) { // catch connection error and rethrow std::cerr << "Failed to activate gripper"; throw; @@ -119,14 +109,11 @@ void RobotiqGripperInterface::activateGripper() void RobotiqGripperInterface::deactivateGripper() { - const auto cmd = createWriteCommand(kActionRequestRegister, { 0x0000, 0x0000, 0x0000 }); - try - { + const auto cmd = createWriteCommand(kActionRequestRegister, {0x0000, 0x0000, 0x0000}); + try { sendCommand(cmd); readResponse(kWriteResponseSize); - } - catch (const serial::IOException& e) - { + } catch (const serial::IOException & e) { // catch connection error and rethrow std::cerr << "Failed to activate gripper"; throw; @@ -139,22 +126,21 @@ void RobotiqGripperInterface::setGripperPosition(uint8_t pos) uint8_t gripper_options_1 = 0x00; uint8_t gripper_options_2 = 0x00; - const auto cmd = - createWriteCommand(kActionRequestRegister, - { uint16_t(action_register << 8 | gripper_options_1), uint16_t(gripper_options_2 << 8 | pos), - uint16_t(commanded_gripper_speed_ << 8 | commanded_gripper_force_) }); - try - { + const auto cmd = createWriteCommand( + kActionRequestRegister, + {uint16_t(action_register << 8 | gripper_options_1), uint16_t(gripper_options_2 << 8 | pos), + uint16_t(commanded_gripper_speed_ << 8 | commanded_gripper_force_)}); + try { sendCommand(cmd); readResponse(kWriteResponseSize); - } - catch (const serial::IOException& e) - { + } catch (const serial::IOException & e) { // catch connection error and rethrow std::cerr << "Failed to set gripper position\n"; - if (port_.isOpen()) - { - std::cerr << "Error caught while reading or writing to device. Connection is open, continuing to attempt communication with gripper.\n ERROR: " << e.what(); + if (port_.isOpen()) { + std::cerr << "Error caught while reading or writing to device. Connection is open, " + "continuing to attempt " + "communication with gripper.\n ERROR: " + << e.what(); return; } throw; @@ -163,12 +149,9 @@ void RobotiqGripperInterface::setGripperPosition(uint8_t pos) uint8_t RobotiqGripperInterface::getGripperPosition() { - try - { + try { updateStatus(); - } - catch (const serial::IOException& e) - { + } catch (const serial::IOException & e) { // catch connection error and rethrow std::cerr << "Failed to get gripper position\n"; throw; @@ -179,12 +162,9 @@ uint8_t RobotiqGripperInterface::getGripperPosition() bool RobotiqGripperInterface::gripperIsMoving() { - try - { + try { updateStatus(); - } - catch (const serial::IOException& e) - { + } catch (const serial::IOException & e) { // catch connection error and rethrow std::cerr << "Failed to get gripper position\n"; throw; @@ -193,45 +173,41 @@ bool RobotiqGripperInterface::gripperIsMoving() return object_detection_status_ == ObjectDetectionStatus::MOVING; } -std::vector RobotiqGripperInterface::createReadCommand(uint16_t first_register, uint8_t num_registers) +std::vector RobotiqGripperInterface::createReadCommand( + uint16_t first_register, uint8_t num_registers) { - std::vector cmd = { slave_id_, - kReadFunctionCode, - getFirstByte(first_register), - getSecondByte(first_register), - getFirstByte(num_registers), - getSecondByte(num_registers) }; + std::vector cmd = { + slave_id_, + kReadFunctionCode, + getFirstByte(first_register), + getSecondByte(first_register), + getFirstByte(num_registers), + getSecondByte(num_registers)}; auto crc = computeCRC(cmd); cmd.push_back(getFirstByte(crc)); cmd.push_back(getSecondByte(crc)); return cmd; } -void RobotiqGripperInterface::setSpeed(uint8_t speed) -{ - commanded_gripper_speed_ = speed; -} +void RobotiqGripperInterface::setSpeed(uint8_t speed) { commanded_gripper_speed_ = speed; } -void RobotiqGripperInterface::setForce(uint8_t force) -{ - commanded_gripper_force_ = force; -} +void RobotiqGripperInterface::setForce(uint8_t force) { commanded_gripper_force_ = force; } -std::vector RobotiqGripperInterface::createWriteCommand(uint16_t first_register, - const std::vector& data) +std::vector RobotiqGripperInterface::createWriteCommand( + uint16_t first_register, const std::vector & data) { uint16_t num_registers = data.size(); uint8_t num_bytes = 2 * num_registers; - std::vector cmd = { slave_id_, - kWriteFunctionCode, - getFirstByte(first_register), - getSecondByte(first_register), - getFirstByte(num_registers), - getSecondByte(num_registers), - num_bytes }; - for (auto d : data) - { + std::vector cmd = { + slave_id_, + kWriteFunctionCode, + getFirstByte(first_register), + getSecondByte(first_register), + getFirstByte(num_registers), + getSecondByte(num_registers), + num_bytes}; + for (auto d : data) { cmd.push_back(getFirstByte(d)); cmd.push_back(getSecondByte(d)); } @@ -248,24 +224,22 @@ std::vector RobotiqGripperInterface::readResponse(size_t num_bytes_requ std::vector response; size_t num_bytes_read = port_.read(response, num_bytes_requested); - if (num_bytes_read != num_bytes_requested) - { - const auto error_msg = - "Requested " + std::to_string(num_bytes_requested) + " bytes, but only got " + std::to_string(num_bytes_read); + if (num_bytes_read != num_bytes_requested) { + const auto error_msg = "Requested " + std::to_string(num_bytes_requested) + + " bytes, but only got " + std::to_string(num_bytes_read); THROW(serial::IOException, error_msg.c_str()); } return response; } -void RobotiqGripperInterface::sendCommand(const std::vector& cmd) +void RobotiqGripperInterface::sendCommand(const std::vector & cmd) { size_t num_bytes_written = port_.write(cmd); port_.flush(); - if (num_bytes_written != cmd.size()) - { - const auto error_msg = "Attempted to write " + std::to_string(cmd.size()) + " bytes, but only wrote " + - std::to_string(num_bytes_written); + if (num_bytes_written != cmd.size()) { + const auto error_msg = "Attempted to write " + std::to_string(cmd.size()) + + " bytes, but only wrote " + std::to_string(num_bytes_written); THROW(serial::IOException, error_msg.c_str()); } } @@ -273,8 +247,7 @@ void RobotiqGripperInterface::sendCommand(const std::vector& cmd) void RobotiqGripperInterface::updateStatus() { // Tell the gripper that we want to read its status. - try - { + try { sendCommand(read_command_); const auto response = readResponse(kReadResponseSize); @@ -283,14 +256,15 @@ void RobotiqGripperInterface::updateStatus() uint8_t gripper_status_byte = response[kResponseHeaderSize + kGripperStatusIndex]; // Activation status. - activation_status_ = ((gripper_status_byte & 0x01) == 0x00) ? ActivationStatus::RESET : ActivationStatus::ACTIVE; + activation_status_ = + ((gripper_status_byte & 0x01) == 0x00) ? ActivationStatus::RESET : ActivationStatus::ACTIVE; // Action status. - action_status_ = ((gripper_status_byte & 0x08) == 0x00) ? ActionStatus::STOPPED : ActionStatus::MOVING; + action_status_ = + ((gripper_status_byte & 0x08) == 0x00) ? ActionStatus::STOPPED : ActionStatus::MOVING; // Gripper status. - switch ((gripper_status_byte & 0x30) >> 4) - { + switch ((gripper_status_byte & 0x30) >> 4) { case 0x00: gripper_status_ = GripperStatus::RESET; break; @@ -303,8 +277,7 @@ void RobotiqGripperInterface::updateStatus() } // Object detection status. - switch ((gripper_status_byte & 0xC0) >> 6) - { + switch ((gripper_status_byte & 0xC0) >> 6) { case 0x00: object_detection_status_ = ObjectDetectionStatus::MOVING; break; @@ -321,13 +294,13 @@ void RobotiqGripperInterface::updateStatus() // Read the current gripper position. gripper_position_ = response[kResponseHeaderSize + kPositionIndex]; - } - catch (const serial::IOException& e) - { + } catch (const serial::IOException & e) { std::cerr << "Failed to update gripper status.\n"; - if (port_.isOpen()) - { - std::cerr << "Error caught while reading or writing to device. Connection is open, continuing to attempt communication with gripper.\n ERROR: " << e.what(); + if (port_.isOpen()) { + std::cerr << "Error caught while reading or writing to device. Connection is open, " + "continuing to attempt " + "communication with gripper.\n ERROR: " + << e.what(); return; } throw; diff --git a/ros2_robotiq_gripper-not-released.humble.repos b/ros2_robotiq_gripper-not-released.humble.repos new file mode 100644 index 0000000..510d9bc --- /dev/null +++ b/ros2_robotiq_gripper-not-released.humble.repos @@ -0,0 +1,5 @@ +repositories: + serial: + type: git + url: https://github.com/tylerjw/serial.git + version: ros2 diff --git a/ros2_robotiq_gripper-not-released.iron.repos b/ros2_robotiq_gripper-not-released.iron.repos new file mode 100644 index 0000000..510d9bc --- /dev/null +++ b/ros2_robotiq_gripper-not-released.iron.repos @@ -0,0 +1,5 @@ +repositories: + serial: + type: git + url: https://github.com/tylerjw/serial.git + version: ros2 diff --git a/ros2_robotiq_gripper-not-released.rolling.repos b/ros2_robotiq_gripper-not-released.rolling.repos new file mode 100644 index 0000000..510d9bc --- /dev/null +++ b/ros2_robotiq_gripper-not-released.rolling.repos @@ -0,0 +1,5 @@ +repositories: + serial: + type: git + url: https://github.com/tylerjw/serial.git + version: ros2 diff --git a/ros2_robotiq_gripper.humble.repos b/ros2_robotiq_gripper.humble.repos new file mode 100644 index 0000000..510d9bc --- /dev/null +++ b/ros2_robotiq_gripper.humble.repos @@ -0,0 +1,5 @@ +repositories: + serial: + type: git + url: https://github.com/tylerjw/serial.git + version: ros2 diff --git a/ros2_robotiq_gripper.iron.repos b/ros2_robotiq_gripper.iron.repos new file mode 100644 index 0000000..510d9bc --- /dev/null +++ b/ros2_robotiq_gripper.iron.repos @@ -0,0 +1,5 @@ +repositories: + serial: + type: git + url: https://github.com/tylerjw/serial.git + version: ros2 diff --git a/ros2_robotiq_gripper.rolling.repos b/ros2_robotiq_gripper.rolling.repos new file mode 100644 index 0000000..510d9bc --- /dev/null +++ b/ros2_robotiq_gripper.rolling.repos @@ -0,0 +1,5 @@ +repositories: + serial: + type: git + url: https://github.com/tylerjw/serial.git + version: ros2