diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..f1bd146 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,13 @@ +# See: https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file#about-the-dependabotyml-file +version: 2 + +updates: + # Configure check for outdated GitHub Actions actions in workflows. + # Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/dependabot/README.md + # See: https://docs.github.com/code-security/dependabot/working-with-dependabot/keeping-your-actions-up-to-date-with-dependabot + - package-ecosystem: github-actions + directory: / # Check the repository's workflows under /.github/workflows/ + schedule: + interval: daily + labels: + - "topic: ci" diff --git a/.github/workflows/ros2.yml b/.github/workflows/ros2.yml new file mode 100644 index 0000000..9ec1f6b --- /dev/null +++ b/.github/workflows/ros2.yml @@ -0,0 +1,52 @@ +name: ros2 + +on: + push: + paths: + - ".github/workflows/ros2.yml" + - "include/**" + - "launch/**" + - "src/**" + - "CMakeLists.txt" + - "package.xml" + pull_request: + paths: + - ".github/workflows/ros2.yml" + - "include/**" + - "launch/**" + - "src/**" + - "CMakeLists.txt" + - "package.xml" + +env: + BUILD_TYPE: Release + +jobs: + build: + name: Build on ros2 ${{ matrix.ros_distro }} + runs-on: ubuntu-22.04 + strategy: + matrix: + ros_distro: [ humble ] + + steps: + - uses: ros-tooling/setup-ros@v0.7 + with: + required-ros-distributions: ${{ matrix.ros_distro }} + + - name: Setup ros2 workspace + run: | + source /opt/ros/${{ matrix.ros_distro }}/setup.bash + mkdir -p ${{github.workspace}}/ros2_ws/src + cd ${{github.workspace}}/ros2_ws + colcon build + + - uses: actions/checkout@v4 + with: + path: 'ros2_ws/src/t07_ros' + + - name: colcon build + run: | + source /opt/ros/${{ matrix.ros_distro }}/setup.bash + cd ${{github.workspace}}/ros2_ws + colcon build --event-handlers console_direct+ diff --git a/.github/workflows/spell-check.yml b/.github/workflows/spell-check.yml new file mode 100644 index 0000000..5552860 --- /dev/null +++ b/.github/workflows/spell-check.yml @@ -0,0 +1,26 @@ +# Source: https://github.com/per1234/.github/blob/main/workflow-templates/spell-check.md +name: Spell Check + +# See: https://docs.github.com/en/actions/reference/events-that-trigger-workflows +on: + push: + pull_request: + schedule: + # Run every Tuesday at 8 AM UTC to catch new misspelling detections resulting from dictionary updates. + - cron: "0 8 * * TUE" + workflow_dispatch: + repository_dispatch: + +permissions: + contents: read + +jobs: + spellcheck: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Spell check + uses: codespell-project/actions-codespell@master diff --git a/.github/workflows/sync-labels.yml b/.github/workflows/sync-labels.yml new file mode 100644 index 0000000..b580030 --- /dev/null +++ b/.github/workflows/sync-labels.yml @@ -0,0 +1,132 @@ +# Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/sync-labels.md +name: Sync Labels + +# See: https://docs.github.com/en/actions/reference/events-that-trigger-workflows +on: + push: + paths: + - ".github/workflows/sync-labels.ya?ml" + - ".github/label-configuration-files/*.ya?ml" + pull_request: + paths: + - ".github/workflows/sync-labels.ya?ml" + - ".github/label-configuration-files/*.ya?ml" + schedule: + # run every Tuesday at 3 AM UTC + - cron: "0 3 * * 2" + workflow_dispatch: + repository_dispatch: + +env: + CONFIGURATIONS_FOLDER: .github/label-configuration-files + CONFIGURATIONS_ARTIFACT: label-configuration-files + +jobs: + check: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Download JSON schema for labels configuration file + id: download-schema + uses: carlosperate/download-file-action@v2.0.1 + with: + file-url: https://raw.githubusercontent.com/arduino/tooling-project-assets/main/workflow-templates/assets/sync-labels/arduino-tooling-gh-label-configuration-schema.json + location: ${{ runner.temp }}/label-configuration-schema + + - name: Install JSON schema validator + run: | + sudo npm install \ + --global \ + ajv-cli \ + ajv-formats + + - name: Validate local labels configuration + run: | + # See: https://github.com/ajv-validator/ajv-cli#readme + ajv validate \ + --all-errors \ + -c ajv-formats \ + -s "${{ steps.download-schema.outputs.file-path }}" \ + -d "${{ env.CONFIGURATIONS_FOLDER }}/*.{yml,yaml}" + + download: + needs: check + runs-on: ubuntu-latest + + strategy: + matrix: + filename: + # Filenames of the shared configurations to apply to the repository in addition to the local configuration. + # https://github.com/107-systems/.github/blob/main/workflow-templates/assets/sync-labels + - universal.yml + + steps: + - name: Download + uses: carlosperate/download-file-action@v2.0.1 + with: + file-url: https://raw.githubusercontent.com/107-systems/.github/main/workflow-templates/assets/sync-labels/${{ matrix.filename }} + + - name: Pass configuration files to next job via workflow artifact + uses: actions/upload-artifact@v3 + with: + path: | + *.yaml + *.yml + if-no-files-found: error + name: ${{ env.CONFIGURATIONS_ARTIFACT }} + + sync: + needs: download + runs-on: ubuntu-latest + + steps: + - name: Set environment variables + run: | + # See: https://docs.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-an-environment-variable + echo "MERGED_CONFIGURATION_PATH=${{ runner.temp }}/labels.yml" >> "$GITHUB_ENV" + + - name: Determine whether to dry run + id: dry-run + if: > + github.event == 'pull_request' || + github.ref != format('refs/heads/{0}', github.event.repository.default_branch) + run: | + # Use of this flag in the github-label-sync command will cause it to only check the validity of the + # configuration. + echo "::set-output name=flag::--dry-run" + + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Download configuration files artifact + uses: actions/download-artifact@v3 + with: + name: ${{ env.CONFIGURATIONS_ARTIFACT }} + path: ${{ env.CONFIGURATIONS_FOLDER }} + + - name: Remove unneeded artifact + uses: geekyeggo/delete-artifact@v2 + with: + name: ${{ env.CONFIGURATIONS_ARTIFACT }} + + - name: Merge label configuration files + run: | + # Merge all configuration files + shopt -s extglob + cat "${{ env.CONFIGURATIONS_FOLDER }}"/*.@(yml|yaml) > "${{ env.MERGED_CONFIGURATION_PATH }}" + + - name: Install github-label-sync + run: sudo npm install --global github-label-sync + + - name: Sync labels + env: + GITHUB_ACCESS_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + # See: https://github.com/Financial-Times/github-label-sync + github-label-sync \ + --labels "${{ env.MERGED_CONFIGURATION_PATH }}" \ + ${{ steps.dry-run.outputs.flag }} \ + ${{ github.repository }} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..86cc9ec --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +build +log +install +**/__pycache__ +.vscode +.idea/ +cmake-build-debug/ diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..fc9ff97 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,40 @@ +####################################################################################### +cmake_minimum_required(VERSION 3.8) +####################################################################################### +project(t07_ros) +set(T07_ROS_TARGET ${PROJECT_NAME}_node) +####################################################################################### +if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") + add_compile_options(-Wall -Wextra -Wpedantic) +endif() +####################################################################################### +# find dependencies +find_package(ament_cmake REQUIRED) +find_package(rclcpp REQUIRED) +####################################################################################### +include_directories( + include +) +####################################################################################### +add_executable(${T07_ROS_TARGET} + src/Node.cpp + src/main.cpp +) +####################################################################################### +target_compile_features(${T07_ROS_TARGET} PRIVATE cxx_std_17) +ament_target_dependencies(${T07_ROS_TARGET} rclcpp) +####################################################################################### +if(BUILD_TESTING) + find_package(ament_lint_auto REQUIRED) + # the following line skips the linter which checks for copyrights + # comment the line when a copyright and license is added to all source files + set(ament_cmake_copyright_FOUND TRUE) + # the following line skips cpplint (only works in a git repo) + # 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) + ament_lint_auto_find_test_dependencies() +endif() +####################################################################################### +ament_package() +####################################################################################### diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..b154e47 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 Alexander Entinger, MSc / LXRobotics GmbH + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..8548d6f --- /dev/null +++ b/README.md @@ -0,0 +1,32 @@ + +:floppy_disk: `t07_ros` +======================= +[![Build Status](https://github.com/107-systems/l3xz_joy/actions/workflows/ros2.yml/badge.svg)](https://github.com/107-systems/l3xz_joy/actions/workflows/ros2.yml) +[![Spell Check status](https://github.com/107-systems/l3xz_joy/actions/workflows/spell-check.yml/badge.svg)](https://github.com/107-systems/l3xz_joy/actions/workflows/spell-check.yml) + +ROS control code for the [T07](https://github.com/107-systems/T07) robot. + +#### How-to-build +```bash +cd $COLCON_WS/src +git clone https://github.com/107-systems/t07_ros +cd $COLCON_WS +source /opt/ros/humble/setup.bash +colcon build --packages-select t07_ros +``` + +#### How-to-run +```bash +cd $COLCON_WS +. install/setup.bash +ros2 launch t07_ros t07.py +``` + +#### Interface Documentation +##### Published Topics +| Default name | Type | +|:------------:|:------------------------------------------------------------------------------:| + +##### Parameters +| Name | Default | Description | +|:-------------------------------------:|:----------------:|-----------------------------------------------------------------------------------------------| diff --git a/include/t07_ros/Node.h b/include/t07_ros/Node.h new file mode 100644 index 0000000..a7a8dd3 --- /dev/null +++ b/include/t07_ros/Node.h @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2023 LXRobotics GmbH. + * Author: Alexander Entinger + * Contributors: https://github.com/107-systems/t07_ros/graphs/contributors. + */ + +#pragma once + +/************************************************************************************** + * INCLUDE + **************************************************************************************/ + +#include + +/************************************************************************************** + * NAMESPACE + **************************************************************************************/ + +namespace t07 +{ + +/************************************************************************************** + * CLASS DECLARATION + **************************************************************************************/ + +class Node : public rclcpp::Node +{ +public: + Node(); + ~Node(); + +private: +}; + +/************************************************************************************** + * NAMESPACE + **************************************************************************************/ + +} /* t07 */ diff --git a/launch/t07.py b/launch/t07.py new file mode 100644 index 0000000..ee894c5 --- /dev/null +++ b/launch/t07.py @@ -0,0 +1,16 @@ +from launch import LaunchDescription +from launch_ros.actions import Node + +def generate_launch_description(): + return LaunchDescription([ + Node( + package='t07_ros', + executable='t07_ros_node', + name='t07_ros', + namespace='t07', + output='screen', + emulate_tty=True, + parameters=[ + ] + ) + ]) diff --git a/package.xml b/package.xml new file mode 100644 index 0000000..e5bab6b --- /dev/null +++ b/package.xml @@ -0,0 +1,20 @@ + + + + t07_ros + 1.0.0 + ROS control code for the T07 robot. + alex + MIT + + ament_cmake + + rclcpp + + ament_lint_auto + ament_lint_common + + + ament_cmake + + diff --git a/src/Node.cpp b/src/Node.cpp new file mode 100644 index 0000000..d486780 --- /dev/null +++ b/src/Node.cpp @@ -0,0 +1,41 @@ +/** + * Copyright (c) 2023 LXRobotics GmbH. + * Author: Alexander Entinger + * Contributors: https://github.com/107-systems/t07_ros/graphs/contributors. + */ + +/************************************************************************************** + * INCLUDE + **************************************************************************************/ + +#include + +/************************************************************************************** + * NAMESPACE + **************************************************************************************/ + +namespace t07 +{ + +/************************************************************************************** + * CTOR/DTOR + **************************************************************************************/ + +Node::Node() +: rclcpp::Node("t07_ros_node") +{ +} + +Node::~Node() +{ +} + +/************************************************************************************** + * PRIVATE MEMBER FUNCTIONS + **************************************************************************************/ + +/************************************************************************************** + * NAMESPACE + **************************************************************************************/ + +} /* t07 */ diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..11324d6 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,41 @@ +/** + * Copyright (c) 2023 LXRobotics GmbH. + * Author: Alexander Entinger + * Contributors: https://github.com/107-systems/t07_ros/graphs/contributors. + */ + +/************************************************************************************** + * INCLUDE + **************************************************************************************/ + +#include + +#include + +/************************************************************************************** + * MAIN + **************************************************************************************/ + +int main(int argc, char * argv[]) +{ + rclcpp::init(argc, argv); + + auto node = std::make_shared(); + + try + { + rclcpp::spin(node); + rclcpp::shutdown(); + return EXIT_SUCCESS; + } + catch (std::runtime_error const & err) + { + RCLCPP_ERROR(rclcpp::get_logger(node->get_name()), "Exception (std::runtime_error) caught: %s\nTerminating ...", err.what()); + return EXIT_FAILURE; + } + catch (...) + { + RCLCPP_ERROR(rclcpp::get_logger(node->get_name()), "Unhandled exception caught.\nTerminating ..."); + return EXIT_FAILURE; + } +}