diff --git a/.config/.yamllint.yaml b/.config/.yamllint.yaml new file mode 100644 index 0000000..3dc9900 --- /dev/null +++ b/.config/.yamllint.yaml @@ -0,0 +1,12 @@ +--- +extends: default + +rules: + line-length: + max: 256 + commas: false + + truthy: + ignore: | + .github/workflows/build_base_images.yml + .github/workflows/build_and_unitest.yml diff --git a/.config/clang-format b/.config/clang-format new file mode 100644 index 0000000..b5f083f --- /dev/null +++ b/.config/clang-format @@ -0,0 +1,69 @@ +--- +# C++ Formatting rules for WATonomous Standard + +# See https://releases.llvm.org/14.0.0/tools/clang/docs/ClangFormatStyleOptions.html for documentation of these options +BasedOnStyle: Google +IndentWidth: 2 +ColumnLimit: 120 + +AccessModifierOffset: -2 +AlignAfterOpenBracket: AlwaysBreak +AlignConsecutiveAssignments: None +AlignConsecutiveDeclarations: None +AlignEscapedNewlines: Left +AlignTrailingComments: false +AllowAllArgumentsOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: Empty +AllowShortFunctionsOnASingleLine: false +BinPackArguments: false +BinPackParameters: false +BraceWrapping: + AfterClass: true + AfterControlStatement: MultiLine + AfterEnum: true + AfterFunction: true + AfterNamespace: true + AfterStruct: true + AfterUnion: true + AfterExternBlock: true + BeforeCatch: false + BeforeElse: false + BeforeLambdaBody: false + BeforeWhile: false + IndentBraces: false + SplitEmptyFunction: false + SplitEmptyRecord: false + SplitEmptyNamespace: false +BreakBeforeBraces: Custom +BreakConstructorInitializers: BeforeComma +CompactNamespaces: false +ContinuationIndentWidth: 2 +ConstructorInitializerIndentWidth: 0 +DerivePointerAlignment: false +EmptyLineAfterAccessModifier: Never +EmptyLineBeforeAccessModifier: LogicalBlock +FixNamespaceComments: true +IncludeBlocks: Regroup +IncludeCategories: + # Headers in <> with .h extension (best guess at C system headers) + - Regex: '<([A-Za-z0-9\Q/-_\E])+\.h>' + Priority: 1 + # Headers in <> without extension (C++ system headers) + - Regex: '<([A-Za-z0-9\Q/-_\E])+>' + Priority: 2 + # Headers in <> with other extensions. + - Regex: '<([A-Za-z0-9.\Q/-_\E])+>' + Priority: 3 + # Headers in "" + - Regex: '"([A-Za-z0-9.\Q/-_\E])+"' + Priority: 4 +IndentAccessModifiers: false +IndentPPDirectives: BeforeHash +PackConstructorInitializers: Never +PointerAlignment: Middle +ReferenceAlignment: Middle +ReflowComments: false +SeparateDefinitionBlocks: Always +SortIncludes: CaseInsensitive +SpacesBeforeTrailingComments: 2 diff --git a/.config/copyright.txt b/.config/copyright.txt new file mode 100644 index 0000000..8f1fadd --- /dev/null +++ b/.config/copyright.txt @@ -0,0 +1,13 @@ +Copyright (c) 2025-present WATonomous. All rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/.cpplint.cfg b/.cpplint.cfg new file mode 100644 index 0000000..522dfc6 --- /dev/null +++ b/.cpplint.cfg @@ -0,0 +1,14 @@ +# Because of cpplint's config file assumptions, this can't be contained in .config/ directory +linelength=256 + +filter=-legal/copyright +filter=-build/header_guard +filter=-build/c++17 + +# Disable all formatting checks, this is handled by clang-format +filter=-readability/braces +filter=-whitespace/braces +filter=-whitespace/indent +filter=-whitespace/newline +filter=-whitespace/parens +filter=-whitespace/semicolon diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml new file mode 100644 index 0000000..5c0db03 --- /dev/null +++ b/.github/workflows/pre-commit.yml @@ -0,0 +1,32 @@ +--- +name: Pre-commit + +on: + pull_request: + push: + branches: [main] + +jobs: + run-pre-commit: + name: Pre-commit Check + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-python@v5 + with: + python-version: '3.x' + + - name: Install xmllint dependency + run: | + sudo apt-get update -qq + sudo apt-get install -y --no-install-recommends libxml2-utils + + - name: Install pre-commit + run: | + python -m pip install --upgrade pip + pip install pre-commit + + - name: Run pre-commit hooks + run: pre-commit run --all-files diff --git a/.gitignore b/.gitignore index 4fbba83..6b05ebb 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,4 @@ __pycache__ watod-config.local.sh **/.DS_Store -draft_* \ No newline at end of file +draft_* diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/editor.xml b/.idea/editor.xml new file mode 100644 index 0000000..8dcd0a9 --- /dev/null +++ b/.idea/editor.xml @@ -0,0 +1,344 @@ + + + + + diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..d49ac56 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..dcb6b8c --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/.idea/wato_rover.iml b/.idea/wato_rover.iml new file mode 100644 index 0000000..c3a94f6 --- /dev/null +++ b/.idea/wato_rover.iml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..400f5a1 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,115 @@ +--- +# WATonomous Pre-commit Config + +# See https://pre-commit.com for more information on these settings +repos: + # General-purpose sanity checks + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v5.0.0 + hooks: + - id: check-added-large-files + exclude: "src/robot/yolo_inference/models/yolov8.onnx" + - id: check-ast + - id: check-case-conflict + - id: check-merge-conflict + - id: check-shebang-scripts-are-executable + - id: check-symlinks + - id: check-toml + - id: check-xml + - id: end-of-file-fixer + - id: forbid-submodules + - id: mixed-line-ending + - id: trailing-whitespace + + # JSON (supports comments) + - repo: https://gitlab.com/bmares/check-json5 + rev: v1.0.0 + hooks: + - id: check-json5 + files: '\.(json|json5|jsonc)$' + + # Python (formatting + linting) + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.11.5 + hooks: + - id: ruff-format + - id: ruff + args: [--fix] + + # C++ formatting + - repo: https://github.com/pre-commit/mirrors-clang-format + rev: v19.1.7 + hooks: + - id: clang-format + args: ["--style=file:.config/clang-format"] + exclude: 'nlohmann/json\.hpp$' + + # C++ linting + - repo: https://github.com/cpplint/cpplint + rev: 2.0.0 + hooks: + - id: cpplint + args: ["--config=.cpplint.cfg", "--filter=-runtime/references", --quiet, --output=sed] + exclude: 'nlohmann/json\.hpp$' + + # CMake linting + - repo: https://github.com/cmake-lint/cmake-lint + rev: 1.4.3 + hooks: + - id: cmakelint + args: [--linelength=140] + + # Bash / Shell scripts + - repo: https://github.com/shellcheck-py/shellcheck-py + rev: v0.10.0.1 + hooks: + - id: shellcheck + args: [-e, SC1091] + + # Dockerfile linting + - repo: https://github.com/AleksaC/hadolint-py + rev: v2.12.1b3 + hooks: + - id: hadolint + args: [--ignore, SC1091, --ignore, DL3006, --ignore, DL3008] + + # Markdown linting + - repo: https://github.com/jackdewinter/pymarkdown + rev: v0.9.28 + hooks: + - id: pymarkdown + args: [-d, MD013, -d, MD029, -d, MD031, fix] + + # XML (ROS-specific) + - repo: https://github.com/emersonknapp/ament_xmllint + rev: v0.1 + hooks: + - id: ament_xmllint + + # YAML linting + - repo: https://github.com/adrienverge/yamllint.git + rev: v1.29.0 + hooks: + - id: yamllint + args: ["-c", ".config/.yamllint.yaml"] + + # License headers + - repo: https://github.com/Lucas-C/pre-commit-hooks + rev: v1.5.5 + hooks: + - id: insert-license + types_or: [python, cmake, shell] + name: Copyright headers for Python/CMake + args: + [ + --license-filepath, + .config/copyright.txt, + --comment-style, + "#", + --allow-past-years, + --no-extra-eol, + ] + - id: insert-license + types_or: [c++, c] + name: Copyright headers for C/C++ + args: [--license-filepath, .config/copyright.txt, --comment-style, "//", --allow-past-years] diff --git a/README.md b/README.md index dd0cf91..48985b6 100644 --- a/README.md +++ b/README.md @@ -8,5 +8,3 @@ These steps are to setup the repo to work on your own PC. We utilize docker to e 1. This repo is supported on Linux Ubuntu >= 22.04, Windows (WSL), and MacOS. This is standard practice that roboticists can't get around. To setup, you can either setup an [Ubuntu Virtual Machine](https://ubuntu.com/tutorials/how-to-run-ubuntu-desktop-on-a-virtual-machine-using-virtualbox#1-overview), setting up [WSL](https://learn.microsoft.com/en-us/windows/wsl/install), or setting up your computer to [dual boot](https://opensource.com/article/18/5/dual-boot-linux). You can find online resources for all three approaches. 2. Once inside Linux, [Download Docker Engine using the `apt` repository](https://docs.docker.com/engine/install/ubuntu/#install-using-the-repository) 3. You're all set! You can visit the [WATO Wiki](https://wiki.watonomous.ca/autonomous_software_general/monorepo_infrastructure) for more documentation on the WATO infrastructure. - - diff --git a/config/rover_foxglove_config.json b/config/rover_foxglove_config.json index fda3dbb..906e84f 100644 --- a/config/rover_foxglove_config.json +++ b/config/rover_foxglove_config.json @@ -493,4 +493,4 @@ "direction": "row", "splitPercentage": 25.272610647851184 } -} \ No newline at end of file +} diff --git a/config/wato_asd_training_foxglove_config .json b/config/wato_asd_training_foxglove_config .json index e9ea578..58a3bf7 100644 --- a/config/wato_asd_training_foxglove_config .json +++ b/config/wato_asd_training_foxglove_config .json @@ -136,7 +136,8 @@ "instanceId": "9e830917-d6fe-4f25-8e7b-25afa5a47d21", "layerId": "foxglove.Urdf", "sourceType": "url", - "url": "https://raw.githubusercontent.com/WATonomous/wato_asd_training/refs/heads/main/src/gazebo/launch/robot.urdf", + "url": + "https://raw.githubusercontent.com/WATonomous/wato_asd_training/refs/heads/main/src/gazebo/launch/robot.urdf", "filePath": "", "parameter": "", "topic": "", @@ -174,7 +175,8 @@ "instanceId": "cadf14d8-072e-4af6-8fd0-60bf81d00399", "layerId": "foxglove.Urdf", "sourceType": "url", - "url": "https://raw.githubusercontent.com/WATonomous/wato_asd_training/refs/heads/main/src/gazebo/launch/env.urdf", + "url": + "https://raw.githubusercontent.com/WATonomous/wato_asd_training/refs/heads/main/src/gazebo/launch/env.urdf", "filePath": "", "parameter": "", "topic": "", @@ -275,4 +277,4 @@ "direction": "row", "splitPercentage": 65.85648148148148 } -} \ No newline at end of file +} diff --git a/custom_images/Dockerfile.clean_base_arm64 b/custom_images/Dockerfile.clean_base_arm64 index dc5b759..e0106d2 100644 --- a/custom_images/Dockerfile.clean_base_arm64 +++ b/custom_images/Dockerfile.clean_base_arm64 @@ -1,13 +1,15 @@ FROM ghcr.io/watonomous/robot_base/base:humble-arm64 # Remove conflicting ROS sources and keyrings +SHELL ["/bin/bash", "-o", "pipefail", "-c"] RUN rm -f /etc/apt/sources.list.d/ros2* && \ rm -f /usr/share/keyrings/ros2-* && \ rm -f /usr/share/keyrings/ros-* && \ - apt-get update && apt-get install -y curl gnupg lsb-release && \ + apt-get update && apt-get install -y --no-install-recommends curl gnupg lsb-release && \ curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key \ | gpg --dearmor -o /usr/share/keyrings/ros-archive-keyring.gpg && \ echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] \ http://packages.ros.org/ros2/ubuntu $(lsb_release -cs) main" \ > /etc/apt/sources.list.d/ros2.list && \ - apt-get update + apt-get update && \ + rm -rf /var/lib/apt/lists/* diff --git a/docker/gazebo/gazeboserver.Dockerfile b/docker/gazebo/gazeboserver.Dockerfile index 7dbae61..bccbd01 100644 --- a/docker/gazebo/gazeboserver.Dockerfile +++ b/docker/gazebo/gazeboserver.Dockerfile @@ -5,13 +5,15 @@ FROM ${BASE_IMAGE} AS source WORKDIR ${AMENT_WS}/src -# Copy in source code +# Copy in source code COPY src/gazebo gazebo -RUN apt-get update && apt-get install -y curl \ - && curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg +RUN apt-get update && apt-get install -y --no-install-recommends curl \ + && curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg \ + && rm -rf /var/lib/apt/lists/* # Scan for rosdeps +SHELL ["/bin/bash", "-o", "pipefail", "-c"] RUN apt-get -qq update && rosdep update && \ (rosdep install --from-paths . --ignore-src -r -s \ | grep 'apt-get install' \ @@ -20,24 +22,27 @@ RUN apt-get -qq update && rosdep update && \ ################################# Dependencies ################################ FROM ${BASE_IMAGE} AS dependencies +SHELL ["/bin/bash", "-o", "pipefail", "-c"] -RUN apt-get update && apt-get install -y curl \ - && curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg - -# RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys A4B469963BF863CC -RUN apt-get update && apt-get install ffmpeg libsm6 libxext6 -y +RUN apt-get update && apt-get install -y --no-install-recommends curl \ + && curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg \ + && rm -rf /var/lib/apt/lists/* -RUN apt install -y lsb-release wget gnupg -RUN wget https://packages.osrfoundation.org/gazebo.gpg -O /usr/share/keyrings/pkgs-osrf-archive-keyring.gpg -RUN echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/pkgs-osrf-archive-keyring.gpg] http://packages.osrfoundation.org/gazebo/ubuntu-stable $(lsb_release -cs) main" | tee /etc/apt/sources.list.d/gazebo-stable.list > /dev/null -RUN apt-get -y update -RUN apt-get -y install ros-${ROS_DISTRO}-ros-gz ignition-fortress -RUN echo $GAZEBO_PLUGIN_PATH=/opt/ros/humble/lib +RUN apt-get update && apt-get install -y --no-install-recommends ffmpeg libsm6 libxext6 && \ + rm -rf /var/lib/apt/lists/* + +RUN apt-get update && apt-get install -y --no-install-recommends lsb-release curl gnupg && \ + curl --progress-bar https://packages.osrfoundation.org/gazebo.gpg -o /usr/share/keyrings/pkgs-osrf-archive-keyring.gpg && \ + echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/pkgs-osrf-archive-keyring.gpg] http://packages.osrfoundation.org/gazebo/ubuntu-stable $(lsb_release -cs) main" | tee /etc/apt/sources.list.d/gazebo-stable.list > /dev/null && \ + apt-get -y update && \ + apt-get -y install --no-install-recommends "ros-${ROS_DISTRO}-ros-gz" ignition-fortress && \ + echo "$GAZEBO_PLUGIN_PATH=/opt/ros/humble/lib" && \ + rm -rf /var/lib/apt/lists/* # Install Rosdep requirements COPY --from=source /tmp/colcon_install_list /tmp/colcon_install_list RUN if [ -s /tmp/colcon_install_list ] && ! grep -q "^#" /tmp/colcon_install_list; then \ - apt-fast install -qq -y --no-install-recommends $(cat /tmp/colcon_install_list); \ + xargs -a /tmp/colcon_install_list apt-fast install -qq -y --no-install-recommends; \ fi # Copy in source code from source stage @@ -54,11 +59,11 @@ FROM dependencies AS build # Build ROS2 packages WORKDIR ${AMENT_WS} -RUN . /opt/ros/$ROS_DISTRO/setup.sh && \ +RUN . "/opt/ros/${ROS_DISTRO}/setup.sh" && \ colcon build \ - --cmake-args -DCMAKE_BUILD_TYPE=Release --install-base ${WATONOMOUS_INSTALL} + --cmake-args -DCMAKE_BUILD_TYPE=Release --install-base "${WATONOMOUS_INSTALL}" -# Source and Build Artifact Cleanup +# Source and Build Artifact Cleanup RUN rm -rf src/* build/* devel/* install/* log/* # Entrypoint will run before any CMD on launch. Sources ~/opt//setup.bash and ~/ament_ws/install/setup.bash diff --git a/docker/robot/robot.Dockerfile b/docker/robot/robot.Dockerfile index 90b48e3..454ab5b 100644 --- a/docker/robot/robot.Dockerfile +++ b/docker/robot/robot.Dockerfile @@ -5,10 +5,11 @@ FROM ${BASE_IMAGE} AS source WORKDIR ${AMENT_WS}/src -RUN apt-get update && apt-get install -y curl \ - && curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg +RUN apt-get update && apt-get install -y --no-install-recommends curl \ + && curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg \ + && rm -rf /var/lib/apt/lists/* -# Copy in source code +# Copy in source code COPY src/robot/yolo_inference ./yolo_inference COPY src/robot/object_detection object_detection COPY src/robot/odometry_spoof odometry_spoof @@ -18,11 +19,8 @@ COPY src/robot/arcade_driver arcade_driver COPY src/robot/motor_speed_controller motor_speed_controller COPY src/wato_msgs/drivetrain_msgs drivetrain_msgs - # Scan for rosdeps -RUN apt-get update && apt-get install -y curl \ - && curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg - +SHELL ["/bin/bash", "-o", "pipefail", "-c"] RUN apt-get -qq update && rosdep update && \ (rosdep install --from-paths . --ignore-src -r -s \ | grep 'apt-get install' \ @@ -32,25 +30,27 @@ RUN apt-get -qq update && rosdep update && \ ################################# Dependencies ################################ FROM ${BASE_IMAGE} AS dependencies -# Clean up and update apt-get, then update rosdep - -RUN apt-get update && apt-get install -y curl \ - && curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg +RUN apt-get update && apt-get install -y --no-install-recommends curl \ + && curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg \ + && rm -rf /var/lib/apt/lists/* -RUN sudo apt-get clean && \ - sudo apt-get update && \ - sudo rosdep update +# Clean up and update apt-get, then update rosdep +RUN apt-get clean && \ + apt-get update && \ + rosdep update && \ + rm -rf /var/lib/apt/lists/* # Install Rosdep requirements COPY --from=source /tmp/colcon_install_list /tmp/colcon_install_list RUN apt-get -qq update && \ - if [ -s /tmp/colcon_install_list ] && ! grep -q "^#" /tmp/colcon_install_list; then \ - apt-fast install -qq -y --no-install-recommends $(cat /tmp/colcon_install_list); \ - fi && \ - # fallback that installs librealsense2 ROS packages if not in colcon_install_list - apt-get -qq install -y --no-install-recommends ros-humble-librealsense2* || true + (if [ -s /tmp/colcon_install_list ] && ! grep -q "^#" /tmp/colcon_install_list; then \ + xargs -a /tmp/colcon_install_list apt-fast install -qq -y --no-install-recommends; \ + fi) && \ + apt-get -qq install -y --no-install-recommends ros-humble-librealsense2* && \ + rm -rf /var/lib/apt/lists/* # Copy in source code from source stage +WORKDIR ${AMENT_WS}/src COPY src/robot/object_detection object_detection WORKDIR ${AMENT_WS} COPY --from=source ${AMENT_WS}/src src @@ -63,32 +63,33 @@ RUN apt-get -qq autoremove -y && apt-get -qq autoclean && apt-get -qq clean && \ ################################ Build ################################ FROM dependencies AS build +RUN apt-get update && apt-get install -y --no-install-recommends curl \ + && curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg \ + && rm -rf /var/lib/apt/lists/* # Clean up and update apt-get, then update rosdep +RUN apt-get clean && \ + apt-get update && \ + rosdep update && \ + rm -rf /var/lib/apt/lists/* -RUN apt-get update && apt-get install -y curl \ - && curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg - -RUN sudo apt-get clean && \ - sudo apt-get update && \ - sudo rosdep update - -RUN apt-get update && apt-get install -y \ +RUN apt-get update && apt-get install --no-install-recommends -y \ python3-pip \ python3-dev \ python3-setuptools \ && rm -rf /var/lib/apt/lists/* -RUN pip install onnxruntime -RUN pip3 install "numpy<2.0" +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt +#RUN pip install --no-cache-dir onnxruntime && pip3 install --no-cache-dir "numpy<2.0" # Build ROS2 packages WORKDIR ${AMENT_WS} -RUN . /opt/ros/$ROS_DISTRO/setup.sh && \ +RUN . "/opt/ros/${ROS_DISTRO}/setup.sh" && \ colcon build \ - --cmake-args -DCMAKE_BUILD_TYPE=Release --install-base ${WATONOMOUS_INSTALL} + --cmake-args -DCMAKE_BUILD_TYPE=Release --install-base "${WATONOMOUS_INSTALL}" -# Source and Build Artifact Cleanup +# Source and Build Artifact Cleanup RUN rm -rf src/* build/* devel/* install/* log/* # Entrypoint will run before any CMD on launch. Sources ~/opt//setup.bash and ~/ament_ws/install/setup.bash diff --git a/docker/samples/cpp_aggregator.Dockerfile b/docker/samples/cpp_aggregator.Dockerfile index cbbc143..2ddd514 100644 --- a/docker/samples/cpp_aggregator.Dockerfile +++ b/docker/samples/cpp_aggregator.Dockerfile @@ -5,14 +5,16 @@ FROM ${BASE_IMAGE} AS source WORKDIR ${AMENT_WS}/src -# Copy in source code +# Copy in source code COPY src/samples/cpp/aggregator aggregator COPY src/wato_msgs/sample_msgs sample_msgs -RUN apt-get update && apt-get install -y curl \ - && curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg +RUN apt-get update && apt-get install -y --no-install-recommends curl \ + && curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg \ + && rm -rf /var/lib/apt/lists/* # Scan for rosdeps +SHELL ["/bin/bash", "-o", "pipefail", "-c"] RUN apt-get -qq update && rosdep update && \ rosdep install --from-paths . --ignore-src -r -s \ | grep 'apt-get install' \ @@ -24,7 +26,7 @@ FROM ${BASE_IMAGE} AS dependencies # Install Rosdep requirements COPY --from=source /tmp/colcon_install_list /tmp/colcon_install_list -RUN apt-fast install -qq -y --no-install-recommends $(cat /tmp/colcon_install_list) +RUN xargs -a /tmp/colcon_install_list apt-fast install -qq -y --no-install-recommends # Copy in source code from source stage WORKDIR ${AMENT_WS} @@ -40,11 +42,11 @@ FROM dependencies AS build # Build ROS2 packages WORKDIR ${AMENT_WS} -RUN . /opt/ros/$ROS_DISTRO/setup.sh && \ +RUN . "/opt/ros/${ROS_DISTRO}/setup.sh" && \ colcon build \ - --cmake-args -DCMAKE_BUILD_TYPE=Release --install-base ${WATONOMOUS_INSTALL} + --cmake-args -DCMAKE_BUILD_TYPE=Release --install-base "${WATONOMOUS_INSTALL}" -# Source and Build Artifact Cleanup +# Source and Build Artifact Cleanup RUN rm -rf src/* build/* devel/* install/* log/* # Entrypoint will run before any CMD on launch. Sources ~/opt//setup.bash and ~/ament_ws/install/setup.bash diff --git a/docker/samples/cpp_producer.Dockerfile b/docker/samples/cpp_producer.Dockerfile index 2feb237..37a8d51 100644 --- a/docker/samples/cpp_producer.Dockerfile +++ b/docker/samples/cpp_producer.Dockerfile @@ -5,15 +5,17 @@ FROM ${BASE_IMAGE} AS source WORKDIR ${AMENT_WS}/src -# Copy in source code +# Copy in source code COPY src/samples/cpp/producer producer COPY src/wato_msgs/sample_msgs sample_msgs -RUN apt-get update && apt-get install -y curl \ - && curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg +RUN apt-get update && apt-get install -y --no-install-recommends curl \ + && curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg \ + && rm -rf /var/lib/apt/lists/* # Scan for rosdeps +SHELL ["/bin/bash", "-o", "pipefail", "-c"] RUN apt-get -qq update && rosdep update && \ rosdep install --from-paths . --ignore-src -r -s \ | grep 'apt-get install' \ @@ -25,7 +27,7 @@ FROM ${BASE_IMAGE} AS dependencies # Install Rosdep requirements COPY --from=source /tmp/colcon_install_list /tmp/colcon_install_list -RUN apt-fast install -qq -y --no-install-recommends $(cat /tmp/colcon_install_list) +RUN xargs -a /tmp/colcon_install_list apt-fast install -qq -y --no-install-recommends # Copy in source code from source stage WORKDIR ${AMENT_WS} @@ -41,11 +43,11 @@ FROM dependencies AS build # Build ROS2 packages WORKDIR ${AMENT_WS} -RUN . /opt/ros/$ROS_DISTRO/setup.sh && \ +RUN . "/opt/ros/${ROS_DISTRO}/setup.sh" && \ colcon build \ - --cmake-args -DCMAKE_BUILD_TYPE=Release --install-base ${WATONOMOUS_INSTALL} + --cmake-args -DCMAKE_BUILD_TYPE=Release --install-base "${WATONOMOUS_INSTALL}" -# Source and Build Artifact Cleanup +# Source and Build Artifact Cleanup RUN rm -rf src/* build/* devel/* install/* log/* # Entrypoint will run before any CMD on launch. Sources ~/opt//setup.bash and ~/ament_ws/install/setup.bash diff --git a/docker/samples/cpp_transformer.Dockerfile b/docker/samples/cpp_transformer.Dockerfile index 11c0017..fdd6dd6 100644 --- a/docker/samples/cpp_transformer.Dockerfile +++ b/docker/samples/cpp_transformer.Dockerfile @@ -5,14 +5,16 @@ FROM ${BASE_IMAGE} AS source WORKDIR ${AMENT_WS}/src -# Copy in source code +# Copy in source code COPY src/samples/cpp/transformer transformer COPY src/wato_msgs/sample_msgs sample_msgs -RUN apt-get update && apt-get install -y curl \ - && curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg +RUN apt-get update && apt-get install -y --no-install-recommends curl \ + && curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg \ + && rm -rf /var/lib/apt/lists/* # Scan for rosdeps +SHELL ["/bin/bash", "-o", "pipefail", "-c"] RUN apt-get -qq update && rosdep update && \ rosdep install --from-paths . --ignore-src -r -s \ | grep 'apt-get install' \ @@ -24,7 +26,7 @@ FROM ${BASE_IMAGE} AS dependencies # Install Rosdep requirements COPY --from=source /tmp/colcon_install_list /tmp/colcon_install_list -RUN apt-fast install -qq -y --no-install-recommends $(cat /tmp/colcon_install_list) +RUN xargs -a /tmp/colcon_install_list apt-fast install -qq -y --no-install-recommends # Copy in source code from source stage WORKDIR ${AMENT_WS} @@ -40,11 +42,11 @@ FROM dependencies AS build # Build ROS2 packages WORKDIR ${AMENT_WS} -RUN . /opt/ros/$ROS_DISTRO/setup.sh && \ +RUN . "/opt/ros/${ROS_DISTRO}/setup.sh" && \ colcon build \ - --cmake-args -DCMAKE_BUILD_TYPE=Release --install-base ${WATONOMOUS_INSTALL} + --cmake-args -DCMAKE_BUILD_TYPE=Release --install-base "${WATONOMOUS_INSTALL}" -# Source and Build Artifact Cleanup +# Source and Build Artifact Cleanup RUN rm -rf src/* build/* devel/* install/* log/* # Entrypoint will run before any CMD on launch. Sources ~/opt//setup.bash and ~/ament_ws/install/setup.bash diff --git a/docker/samples/py_aggregator.Dockerfile b/docker/samples/py_aggregator.Dockerfile index fef8576..8a3c740 100644 --- a/docker/samples/py_aggregator.Dockerfile +++ b/docker/samples/py_aggregator.Dockerfile @@ -5,14 +5,16 @@ FROM ${BASE_IMAGE} AS source WORKDIR ${AMENT_WS}/src -# Copy in source code +# Copy in source code COPY src/samples/python/aggregator aggregator COPY src/wato_msgs/sample_msgs sample_msgs -RUN apt-get update && apt-get install -y curl \ - && curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg +RUN apt-get update && apt-get install -y --no-install-recommends curl \ + && curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg \ + && rm -rf /var/lib/apt/lists/* # Scan for rosdeps +SHELL ["/bin/bash", "-o", "pipefail", "-c"] RUN apt-get -qq update && rosdep update && \ rosdep install --from-paths . --ignore-src -r -s \ | grep 'apt-get install' \ @@ -24,7 +26,7 @@ FROM ${BASE_IMAGE} AS dependencies # Install Rosdep requirements COPY --from=source /tmp/colcon_install_list /tmp/colcon_install_list -RUN apt-fast install -qq -y --no-install-recommends $(cat /tmp/colcon_install_list) +RUN xargs -a /tmp/colcon_install_list apt-fast install -qq -y --no-install-recommends # Copy in source code from source stage WORKDIR ${AMENT_WS} @@ -40,11 +42,11 @@ FROM dependencies AS build # Build ROS2 packages WORKDIR ${AMENT_WS} -RUN . /opt/ros/$ROS_DISTRO/setup.sh && \ +RUN . "/opt/ros/${ROS_DISTRO}/setup.sh" && \ colcon build \ - --cmake-args -DCMAKE_BUILD_TYPE=Release --install-base ${WATONOMOUS_INSTALL} + --cmake-args -DCMAKE_BUILD_TYPE=Release --install-base "${WATONOMOUS_INSTALL}" -# Source and Build Artifact Cleanup +# Source and Build Artifact Cleanup RUN rm -rf src/* build/* devel/* install/* log/* # Entrypoint will run before any CMD on launch. Sources ~/opt//setup.bash and ~/ament_ws/install/setup.bash diff --git a/docker/samples/py_producer.Dockerfile b/docker/samples/py_producer.Dockerfile index 6d1f7d7..e44265e 100644 --- a/docker/samples/py_producer.Dockerfile +++ b/docker/samples/py_producer.Dockerfile @@ -5,14 +5,16 @@ FROM ${BASE_IMAGE} AS source WORKDIR ${AMENT_WS}/src -# Copy in source code +# Copy in source code COPY src/samples/python/producer producer COPY src/wato_msgs/sample_msgs sample_msgs -RUN apt-get update && apt-get install -y curl \ - && curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg +RUN apt-get update && apt-get install -y --no-install-recommends curl \ + && curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg \ + && rm -rf /var/lib/apt/lists/* # Scan for rosdeps +SHELL ["/bin/bash", "-o", "pipefail", "-c"] RUN apt-get -qq update && rosdep update && \ rosdep install --from-paths . --ignore-src -r -s \ | grep 'apt-get install' \ @@ -24,7 +26,7 @@ FROM ${BASE_IMAGE} AS dependencies # Install Rosdep requirements COPY --from=source /tmp/colcon_install_list /tmp/colcon_install_list -RUN apt-fast install -qq -y --no-install-recommends $(cat /tmp/colcon_install_list) +RUN xargs -a /tmp/colcon_install_list apt-fast install -qq -y --no-install-recommends # Copy in source code from source stage WORKDIR ${AMENT_WS} @@ -40,11 +42,11 @@ FROM dependencies AS build # Build ROS2 packages WORKDIR ${AMENT_WS} -RUN . /opt/ros/$ROS_DISTRO/setup.sh && \ +RUN . "/opt/ros/${ROS_DISTRO}/setup.sh" && \ colcon build \ - --cmake-args -DCMAKE_BUILD_TYPE=Release --install-base ${WATONOMOUS_INSTALL} + --cmake-args -DCMAKE_BUILD_TYPE=Release --install-base "${WATONOMOUS_INSTALL}" -# Source and Build Artifact Cleanup +# Source and Build Artifact Cleanup RUN rm -rf src/* build/* devel/* install/* log/* # Entrypoint will run before any CMD on launch. Sources ~/opt//setup.bash and ~/ament_ws/install/setup.bash diff --git a/docker/samples/py_transformer.Dockerfile b/docker/samples/py_transformer.Dockerfile index 363ff1b..3cdfacd 100644 --- a/docker/samples/py_transformer.Dockerfile +++ b/docker/samples/py_transformer.Dockerfile @@ -5,14 +5,16 @@ FROM ${BASE_IMAGE} AS source WORKDIR ${AMENT_WS}/src -# Copy in source code +# Copy in source code COPY src/samples/python/transformer transformer COPY src/wato_msgs/sample_msgs sample_msgs -RUN apt-get update && apt-get install -y curl \ - && curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg +RUN apt-get update && apt-get install -y --no-install-recommends curl \ + && curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg \ + && rm -rf /var/lib/apt/lists/* # Scan for rosdeps +SHELL ["/bin/bash", "-o", "pipefail", "-c"] RUN apt-get -qq update && rosdep update && \ rosdep install --from-paths . --ignore-src -r -s \ | grep 'apt-get install' \ @@ -24,7 +26,7 @@ FROM ${BASE_IMAGE} AS dependencies # Install Rosdep requirements COPY --from=source /tmp/colcon_install_list /tmp/colcon_install_list -RUN apt-fast install -qq -y --no-install-recommends $(cat /tmp/colcon_install_list) +RUN xargs -a /tmp/colcon_install_list apt-fast install -qq -y --no-install-recommends # Copy in source code from source stage WORKDIR ${AMENT_WS} @@ -40,11 +42,11 @@ FROM dependencies AS build # Build ROS2 packages WORKDIR ${AMENT_WS} -RUN . /opt/ros/$ROS_DISTRO/setup.sh && \ +RUN . "/opt/ros/${ROS_DISTRO}/setup.sh" && \ colcon build \ - --cmake-args -DCMAKE_BUILD_TYPE=Release --install-base ${WATONOMOUS_INSTALL} + --cmake-args -DCMAKE_BUILD_TYPE=Release --install-base "${WATONOMOUS_INSTALL}" -# Source and Build Artifact Cleanup +# Source and Build Artifact Cleanup RUN rm -rf src/* build/* devel/* install/* log/* # Entrypoint will run before any CMD on launch. Sources ~/opt//setup.bash and ~/ament_ws/install/setup.bash diff --git a/docker/vis_tools/foxglove.Dockerfile b/docker/vis_tools/foxglove.Dockerfile index cc20f9d..6589b13 100644 --- a/docker/vis_tools/foxglove.Dockerfile +++ b/docker/vis_tools/foxglove.Dockerfile @@ -5,13 +5,15 @@ FROM ${BASE_IMAGE} AS source WORKDIR ${AMENT_WS}/src -# Copy in source code +# Copy in source code COPY src/wato_msgs wato_msgs -RUN apt-get update && apt-get install -y curl \ - && curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg +RUN apt-get update && apt-get install -y --no-install-recommends curl \ + && curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg \ + && rm -rf /var/lib/apt/lists/* # Scan for rosdeps +SHELL ["/bin/bash", "-o", "pipefail", "-c"] RUN apt-get -qq update && rosdep update && \ (rosdep install --from-paths . --ignore-src -r -s \ | grep 'apt-get install' \ @@ -21,29 +23,33 @@ RUN apt-get -qq update && rosdep update && \ ################################# Dependencies ################################ FROM ${BASE_IMAGE} AS dependencies -RUN apt-get update && apt-get install -y curl \ - && curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg +RUN apt-get update && apt-get install -y --no-install-recommends curl \ + && curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg \ + && rm -rf /var/lib/apt/lists/* # Install Foxglove Deps -RUN apt-get update && apt-get install -y curl ros-humble-ros2bag ros-humble-rosbag2* ros-humble-foxglove-msgs&& \ +RUN apt-get update && apt-get install -y --no-install-recommends curl ros-humble-ros2bag ros-humble-rosbag2* ros-humble-foxglove-msgs && \ rm -rf /var/lib/apt/lists/* # Set up apt repo -RUN apt-get update && apt-get install -y lsb-release software-properties-common apt-transport-https && \ - apt-add-repository universe +RUN apt-get update && apt-get install -y --no-install-recommends lsb-release software-properties-common apt-transport-https && \ + apt-add-repository universe && \ + rm -rf /var/lib/apt/lists/* +# Install Dependencies # Install Dependencies RUN apt-get update && \ - apt-get install -y \ - ros-$ROS_DISTRO-foxglove-bridge \ - ros-$ROS_DISTRO-rosbridge-server \ - ros-$ROS_DISTRO-topic-tools \ - ros-$ROS_DISTRO-vision-msgs + apt-get install -y --no-install-recommends \ + "ros-${ROS_DISTRO}-foxglove-bridge" \ + "ros-${ROS_DISTRO}-rosbridge-server" \ + "ros-${ROS_DISTRO}-topic-tools" \ + "ros-${ROS_DISTRO}-vision-msgs" && \ + rm -rf /var/lib/apt/lists/* # Install Rosdep requirements COPY --from=source /tmp/colcon_install_list /tmp/colcon_install_list RUN if [ -s /tmp/colcon_install_list ] && ! grep -q "^#" /tmp/colcon_install_list; then \ - apt-fast install -qq -y --no-install-recommends $(cat /tmp/colcon_install_list); \ + xargs -a /tmp/colcon_install_list apt-fast install -qq -y --no-install-recommends < /dev/null; \ fi # Copy in source code from source stage @@ -60,11 +66,11 @@ FROM dependencies AS build # Build ROS2 packages WORKDIR ${AMENT_WS} -RUN . /opt/ros/$ROS_DISTRO/setup.sh && \ +RUN . "/opt/ros/${ROS_DISTRO}/setup.sh" && \ colcon build \ - --cmake-args -DCMAKE_BUILD_TYPE=Release --install-base ${WATONOMOUS_INSTALL} + --cmake-args -DCMAKE_BUILD_TYPE=Release --install-base "${WATONOMOUS_INSTALL}" -# Source and Build Artifact Cleanup +# Source and Build Artifact Cleanup RUN rm -rf src/* build/* devel/* install/* log/* # Entrypoint will run before any CMD on launch. Sources ~/opt//setup.bash and ~/ament_ws/install/setup.bash diff --git a/docker/wato_ros_entrypoint.sh b/docker/wato_ros_entrypoint.sh index df53dae..416080b 100755 --- a/docker/wato_ros_entrypoint.sh +++ b/docker/wato_ros_entrypoint.sh @@ -1,4 +1,17 @@ #!/bin/bash +# Copyright (c) 2025-present WATonomous. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. set -e # setup ROS2 environment diff --git a/modules/docker-compose.robot.yaml b/modules/docker-compose.robot.yaml index f512800..20e37a8 100644 --- a/modules/docker-compose.robot.yaml +++ b/modules/docker-compose.robot.yaml @@ -1,5 +1,5 @@ services: - robot: + robot: build: &robot_build context: .. dockerfile: docker/robot/robot.Dockerfile @@ -17,7 +17,7 @@ services: volumes: - /dev:/dev privileged: true - + robot_dev: build: *robot_build image: "${ROBOT_IMAGE:?}:dev_${TAG}" @@ -29,4 +29,4 @@ services: - /dev:/dev devices: - /dev/bus/usb:/dev/bus/usb - privileged: true \ No newline at end of file + privileged: true diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..26ee264 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,25 @@ +# Core ROS 2 Python dependencies +rclpy +ament-index-python + +# Launch system dependencies +launch +launch-ros + +# Computer Vision and Machine Learning +opencv-python +numpy<2.0 +onnxruntime==1.16.3 +cv-bridge + +# Optional PyTorch support (for .pt model files) +torch ; extra == 'torch' + +# Testing and Linting dependencies +pytest +ament-copyright +ament-flake8 +ament-pep257 + +# Build tools +setuptools diff --git a/scripts/Package-Creation.md b/scripts/Package-Creation.md index 791b386..f03c936 100644 --- a/scripts/Package-Creation.md +++ b/scripts/Package-Creation.md @@ -11,5 +11,3 @@ From root, run `chmod +x scripts/*.sh`. Then run `scripts/add_robot_package.sh < - Creates the `CMakeLists.txt` and `package.xml` files inside `src/robot/new_package`. - Updates [src/robot/bringup_robot](src/robot/bringup_robot)'s `package.xml` file and launch file so that the new package is launched when the `robot` module is brought up (with `watod up` or `watod up robot`). - Adds command to `robot.dockerfile` to copy the new package's source code to the image. - - diff --git a/scripts/add_robot_package.sh b/scripts/add_robot_package.sh index 1ab9c2c..73f037d 100755 --- a/scripts/add_robot_package.sh +++ b/scripts/add_robot_package.sh @@ -1,7 +1,19 @@ #!/usr/bin/env bash +# Copyright (c) 2025-present WATonomous. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. set -euo pipefail -DOCKERFILE="docker/robot/robot.Dockerfile" LAUNCH_FILE="src/robot/bringup_robot/launch/robot.launch.py" BR_PKG_XML="src/robot/bringup_robot/package.xml" TEMPLATE_DIR="templates" @@ -64,7 +76,7 @@ fi echo "Creating new package directory tree at '$dest_root'" while IFS= read -r -d '' templ; do - rel="${templ#$TEMPLATE_DIR/}" + rel="${templ#"$TEMPLATE_DIR"/}" [[ $rel == "params.yaml.in" ]] && rel="config/$rel" rel="${rel//package_name/${pkg}}" rel="${rel%.in}" diff --git a/scripts/insert_package_copy.sh b/scripts/insert_package_copy.sh index 5c7cddc..177654f 100755 --- a/scripts/insert_package_copy.sh +++ b/scripts/insert_package_copy.sh @@ -1,4 +1,17 @@ #!/usr/bin/env bash +# Copyright (c) 2025-present WATonomous. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. # # insert_package_copy.sh # diff --git a/src/gazebo/CMakeLists.txt b/src/gazebo/CMakeLists.txt index 473bca9..1e8c50a 100644 --- a/src/gazebo/CMakeLists.txt +++ b/src/gazebo/CMakeLists.txt @@ -1,3 +1,16 @@ +# Copyright (c) 2025-present WATonomous. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. cmake_minimum_required(VERSION 3.5) project(gazebo) diff --git a/src/gazebo/launch/env.urdf b/src/gazebo/launch/env.urdf index 3e81665..73d6a13 100644 --- a/src/gazebo/launch/env.urdf +++ b/src/gazebo/launch/env.urdf @@ -144,4 +144,4 @@ - \ No newline at end of file + diff --git a/src/gazebo/launch/mars_env.urdf b/src/gazebo/launch/mars_env.urdf index 9ae26e9..c61ed2e 100644 --- a/src/gazebo/launch/mars_env.urdf +++ b/src/gazebo/launch/mars_env.urdf @@ -73,4 +73,4 @@ - \ No newline at end of file + diff --git a/src/gazebo/launch/robot.urdf b/src/gazebo/launch/robot.urdf index 27a1b1d..a0a61a3 100644 --- a/src/gazebo/launch/robot.urdf +++ b/src/gazebo/launch/robot.urdf @@ -11,7 +11,7 @@ - + @@ -50,4 +50,4 @@ - \ No newline at end of file + diff --git a/src/gazebo/launch/robot_env.sdf b/src/gazebo/launch/robot_env.sdf index 2b1508e..e7a6961 100644 --- a/src/gazebo/launch/robot_env.sdf +++ b/src/gazebo/launch/robot_env.sdf @@ -299,11 +299,11 @@ mars.stl - 0.1 0.1 0.1 + 0.1 0.1 0.1 - 0.76 0.60 0.42 1 + 0.76 0.60 0.42 1 0.76 0.60 0.42 1 0 0 0 0 0 3.14159 @@ -327,11 +327,11 @@ water_bottle.stl - 0.4 0.4 0.4 + 0.4 0.4 0.4 - 0.68 0.85 0.90 1 + 0.68 0.85 0.90 1 0.68 0.85 0.90 1 0 0 0 0 0 3.14159 @@ -355,11 +355,11 @@ mallet.stl - 0.4 0.4 0.4 + 0.4 0.4 0.4 - 1 0.4 0.0 1 + 1 0.4 0.0 1 1 0.4 0.0 1 0 0 0 0 0 3.14159 @@ -787,4 +787,4 @@ - \ No newline at end of file + diff --git a/src/gazebo/launch/sim.ign b/src/gazebo/launch/sim.ign index 14eba17..98bb2bf 100644 --- a/src/gazebo/launch/sim.ign +++ b/src/gazebo/launch/sim.ign @@ -6,5 +6,5 @@ 9002 -1 - - \ No newline at end of file + + diff --git a/src/gazebo/launch/sim.launch.py b/src/gazebo/launch/sim.launch.py index a28b584..a482542 100644 --- a/src/gazebo/launch/sim.launch.py +++ b/src/gazebo/launch/sim.launch.py @@ -1,53 +1,63 @@ +# Copyright (c) 2025-present WATonomous. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. import os from ament_index_python.packages import get_package_share_directory from launch import LaunchDescription -from launch.actions import DeclareLaunchArgument from launch.actions import ExecuteProcess -from launch.conditions import IfCondition -from launch.launch_description_sources import PythonLaunchDescriptionSource -from launch.substitutions import LaunchConfiguration from launch_ros.actions import Node + def generate_launch_description(): - gazebo_pkg_prefix = get_package_share_directory('gazebo') - gazebo_sim_ign = os.path.join(gazebo_pkg_prefix, 'launch', 'sim.ign') - sdf_file_path = os.path.join(gazebo_pkg_prefix, 'launch', 'robot_env.sdf') - - gz_sim = ExecuteProcess(cmd=['ign', 'launch', '-v 4', f'{gazebo_sim_ign}']) - gz_sim_server = ExecuteProcess(cmd=['ign', 'gazebo', '-s', '-v 4', '-r', f'{sdf_file_path}']) + gazebo_pkg_prefix = get_package_share_directory("gazebo") + gazebo_sim_ign = os.path.join(gazebo_pkg_prefix, "launch", "sim.ign") + sdf_file_path = os.path.join(gazebo_pkg_prefix, "launch", "robot_env.sdf") + + gz_sim = ExecuteProcess(cmd=["ign", "launch", "-v 4", f"{gazebo_sim_ign}"]) + gz_sim_server = ExecuteProcess( + cmd=["ign", "gazebo", "-s", "-v 4", "-r", f"{sdf_file_path}"] + ) # Bridge bridge = Node( - package='ros_gz_bridge', - executable='parameter_bridge', + package="ros_gz_bridge", + executable="parameter_bridge", arguments=[ - '/model/robot/pose@tf2_msgs/msg/TFMessage@ignition.msgs.Pose_V', - '/model/robot/pose_static@tf2_msgs/msg/TFMessage@ignition.msgs.Pose_V', - '/cmd_vel@geometry_msgs/msg/Twist]ignition.msgs.Twist', - '/cmd_vel_stamped@geometry_msgs/msg/TwistStamped@ignition.msgs.Twist', - '/imu@sensor_msgs/msg/Imu@ignition.msgs.IMU', - '/model/robot/odometry@nav_msgs/msg/Odometry@gz.msgs.Odometry', - '/sim/realsense1/depth/points@sensor_msgs/msg/PointCloud2@ignition.msgs.PointCloudPacked', - '/sim/realsense1/depth/image@sensor_msgs/msg/Image@ignition.msgs.Image', - '/sim/realsense1/depth/camera_info@sensor_msgs/msg/CameraInfo@ignition.msgs.CameraInfo', - '/sim/realsense2/depth/points@sensor_msgs/msg/PointCloud2@ignition.msgs.PointCloudPacked', - '/sim/realsense2/depth/image@sensor_msgs/msg/Image@ignition.msgs.Image', - '/sim/realsense2/depth/camera_info@sensor_msgs/msg/CameraInfo@ignition.msgs.CameraInfo', - '/tf@tf2_msgs/msg/TFMessage@ignition.msgs.Pose_V', + "/model/robot/pose@tf2_msgs/msg/TFMessage@ignition.msgs.Pose_V", + "/model/robot/pose_static@tf2_msgs/msg/TFMessage@ignition.msgs.Pose_V", + "/cmd_vel@geometry_msgs/msg/Twist]ignition.msgs.Twist", + "/cmd_vel_stamped@geometry_msgs/msg/TwistStamped@ignition.msgs.Twist", + "/imu@sensor_msgs/msg/Imu@ignition.msgs.IMU", + "/model/robot/odometry@nav_msgs/msg/Odometry@gz.msgs.Odometry", + "/sim/realsense1/depth/points@sensor_msgs/msg/PointCloud2@ignition.msgs.PointCloudPacked", + "/sim/realsense1/depth/image@sensor_msgs/msg/Image@ignition.msgs.Image", + "/sim/realsense1/depth/camera_info@sensor_msgs/msg/CameraInfo@ignition.msgs.CameraInfo", + "/sim/realsense2/depth/points@sensor_msgs/msg/PointCloud2@ignition.msgs.PointCloudPacked", + "/sim/realsense2/depth/image@sensor_msgs/msg/Image@ignition.msgs.Image", + "/sim/realsense2/depth/camera_info@sensor_msgs/msg/CameraInfo@ignition.msgs.CameraInfo", + "/tf@tf2_msgs/msg/TFMessage@ignition.msgs.Pose_V", ], - parameters=[{'qos_overrides./model/vehicle_blue.subscriber.reliability': 'reliable'}], - output='screen', + parameters=[ + {"qos_overrides./model/vehicle_blue.subscriber.reliability": "reliable"} + ], + output="screen", remappings=[ - ('/model/robot/pose', '/tf'), - ('/model/robot/pose_static', '/tf'), - ] + ("/model/robot/pose", "/tf"), + ("/model/robot/pose_static", "/tf"), + ], ) - return LaunchDescription([ - gz_sim, - gz_sim_server, - bridge - ]) \ No newline at end of file + return LaunchDescription([gz_sim, gz_sim_server, bridge]) diff --git a/src/gazebo/package.xml b/src/gazebo/package.xml index ee0cb31..fb124ae 100644 --- a/src/gazebo/package.xml +++ b/src/gazebo/package.xml @@ -12,4 +12,4 @@ ament_cmake - \ No newline at end of file + diff --git a/src/robot/arcade_driver/CMakeLists.txt b/src/robot/arcade_driver/CMakeLists.txt index ea5681e..d077d56 100644 --- a/src/robot/arcade_driver/CMakeLists.txt +++ b/src/robot/arcade_driver/CMakeLists.txt @@ -1,3 +1,16 @@ +# Copyright (c) 2025-present WATonomous. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. cmake_minimum_required(VERSION 3.10) project(arcade_driver) diff --git a/src/robot/arcade_driver/include/arcade_driver.hpp b/src/robot/arcade_driver/include/arcade_driver.hpp deleted file mode 100644 index ddaa25b..0000000 --- a/src/robot/arcade_driver/include/arcade_driver.hpp +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef ARCADE_DRIVER_NODE_HPP_ -#define ARCADE_DRIVER_NODE_HPP_ - -#include -#include -#include -#include "drivetrain_msgs/msg/arcade_speed.hpp" - -class ArcadeDriver : public rclcpp::Node { - public: - ArcadeDriver(); - - private: - rclcpp::Subscription::SharedPtr joystick_sub_; - rclcpp::Publisher::SharedPtr arcade_pub_; - - drivetrain_msgs::msg::ArcadeSpeed joystick_to_speed_mapper(const float joystick_rotate, const float joystick_drive); - void joystick_callback(const geometry_msgs::msg::TwistStamped::SharedPtr msg); - bool is_negligible_joystick_change(const float new_joystick_rotate, const float new_joystick_drive); - const float THRESHOLD = 0.05; -}; - -#endif diff --git a/src/robot/arcade_driver/include/arcade_driver/arcade_driver.hpp b/src/robot/arcade_driver/include/arcade_driver/arcade_driver.hpp new file mode 100644 index 0000000..d0e60c5 --- /dev/null +++ b/src/robot/arcade_driver/include/arcade_driver/arcade_driver.hpp @@ -0,0 +1,39 @@ +// Copyright (c) 2025-present WATonomous. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef ARCADE_DRIVER_NODE_HPP_ +#define ARCADE_DRIVER_NODE_HPP_ + +#include +#include +#include + +#include "drivetrain_msgs/msg/arcade_speed.hpp" + +class ArcadeDriver : public rclcpp::Node +{ +public: + ArcadeDriver(); + +private: + rclcpp::Subscription::SharedPtr joystick_sub_; + rclcpp::Publisher::SharedPtr arcade_pub_; + + drivetrain_msgs::msg::ArcadeSpeed joystick_to_speed_mapper(const float joystick_rotate, const float joystick_drive); + void joystick_callback(const geometry_msgs::msg::TwistStamped::SharedPtr msg); + bool is_negligible_joystick_change(const float new_joystick_rotate, const float new_joystick_drive); + const float THRESHOLD = 0.05; +}; + +#endif diff --git a/src/robot/arcade_driver/package.xml b/src/robot/arcade_driver/package.xml index 8d67bde..ccf7c59 100644 --- a/src/robot/arcade_driver/package.xml +++ b/src/robot/arcade_driver/package.xml @@ -26,4 +26,4 @@ ament_cmake - \ No newline at end of file + diff --git a/src/robot/arcade_driver/src/arcade_driver.cpp b/src/robot/arcade_driver/src/arcade_driver.cpp index 4f56ea4..c06888b 100644 --- a/src/robot/arcade_driver/src/arcade_driver.cpp +++ b/src/robot/arcade_driver/src/arcade_driver.cpp @@ -1,55 +1,76 @@ -#include "arcade_driver.hpp" +// Copyright (c) 2025-present WATonomous. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "arcade_driver/arcade_driver.hpp" + #include +#include -using namespace std::placeholders; +ArcadeDriver::ArcadeDriver() +: Node("arcade_driver") +{ + // Create publisher for joystick messages + joystick_sub_ = this->create_subscription( + "/cmd_vel_stamped", 10, std::bind(&ArcadeDriver::joystick_callback, this, std::placeholders::_1)); -ArcadeDriver::ArcadeDriver() : Node("arcade_driver") { - // Create publisher for joystick messages - joystick_sub_ = this->create_subscription( - "/cmd_vel_stamped", 10, - std::bind(&ArcadeDriver::joystick_callback, this, _1)); - - arcade_pub_ = this->create_publisher( - "/arcade_speed", 10); + arcade_pub_ = this->create_publisher("/arcade_speed", 10); } // joystick input is "negligible" if it is very close to (0, 0), basically -bool ArcadeDriver::is_negligible_joystick_change(const float new_joystick_rotate, const float new_joystick_drive) { - (void) new_joystick_rotate; - (void) new_joystick_drive; - return false; +bool ArcadeDriver::is_negligible_joystick_change(const float new_joystick_rotate, const float new_joystick_drive) +{ + (void)new_joystick_rotate; + (void)new_joystick_drive; + return false; } -void ArcadeDriver::joystick_callback(const geometry_msgs::msg::TwistStamped::SharedPtr msg) { - // Ignore Twist msg if component is inactive - // if (this->get_current_state().id() != lifecycle_msgs::msg::State::PRIMARY_STATE_ACTIVE) { - // RCLCPP_WARN(get_logger(), "Received twist message while not active, ignoring..."); - // return; - // } +void ArcadeDriver::joystick_callback(const geometry_msgs::msg::TwistStamped::SharedPtr msg) +{ + // Ignore Twist msg if component is inactive + // if (this->get_current_state().id() != lifecycle_msgs::msg::State::PRIMARY_STATE_ACTIVE) { + // RCLCPP_WARN(get_logger(), "Received twist message while not active, ignoring..."); + // return; + // } - RCLCPP_INFO(get_logger(), "Received Twist message - linear.x: %.2f, angular.z: %.2f", - msg->twist.linear.x, msg->twist.angular.z); + RCLCPP_INFO( + get_logger(), + "Received Twist message - linear.x: %.2f, angular.z: %.2f", + msg->twist.linear.x, + msg->twist.angular.z); - float joystick_drive = msg->twist.linear.x; - float joystick_rotate = msg->twist.angular.z; + float joystick_drive = msg->twist.linear.x; + float joystick_rotate = msg->twist.angular.z; - if (is_negligible_joystick_change(joystick_rotate, joystick_drive)) { - RCLCPP_INFO(rclcpp::get_logger("ArcadeDriver"), "Negligibe joystick change"); - return; - } + if (is_negligible_joystick_change(joystick_rotate, joystick_drive)) { + RCLCPP_INFO(rclcpp::get_logger("ArcadeDriver"), "Negligibe joystick change"); + return; + } - drivetrain_msgs::msg::ArcadeSpeed arcade_msg = ArcadeDriver::joystick_to_speed_mapper(joystick_rotate, joystick_drive); - RCLCPP_INFO(get_logger(), "Publishing ArcadeSpeed - left: %.2f, right: %.2f", - arcade_msg.l, arcade_msg.r); - arcade_pub_->publish(std::move(arcade_msg)); + drivetrain_msgs::msg::ArcadeSpeed arcade_msg = + ArcadeDriver::joystick_to_speed_mapper(joystick_rotate, joystick_drive); + RCLCPP_INFO(get_logger(), "Publishing ArcadeSpeed - left: %.2f, right: %.2f", arcade_msg.l, arcade_msg.r); + arcade_pub_->publish(std::move(arcade_msg)); } -drivetrain_msgs::msg::ArcadeSpeed ArcadeDriver::joystick_to_speed_mapper(const float joystick_rotate, const float joystick_drive) { - const float MAX = fmax(fabs(joystick_drive), fabs(joystick_rotate)); - const float DIFF = joystick_drive - joystick_rotate; - const float TOTAL = joystick_drive + joystick_rotate; +drivetrain_msgs::msg::ArcadeSpeed ArcadeDriver::joystick_to_speed_mapper( + const float joystick_rotate, const float joystick_drive) +{ + const float MAX = fmax(fabs(joystick_drive), fabs(joystick_rotate)); + const float DIFF = joystick_drive - joystick_rotate; + const float TOTAL = joystick_drive + joystick_rotate; - /* + /* maximum = max(abs(drive), abs(rotate)) total, difference = drive + rotate, drive - rotate # set speed according to the quadrant that the values are in @@ -69,38 +90,45 @@ drivetrain_msgs::msg::ArcadeSpeed ArcadeDriver::joystick_to_speed_mapper(const f right_motor(difference) */ - float left_motor; - float right_motor; - - if (joystick_drive >= 0) { - if (joystick_rotate >= 0) { - left_motor = MAX; - right_motor = DIFF; - } else { - left_motor = TOTAL; - right_motor = MAX; - } - } else { - if (joystick_rotate >= 0) { - left_motor = TOTAL; - right_motor = -1 * MAX; - } else { - left_motor = -1 * MAX; - right_motor = DIFF; - } - } - - RCLCPP_INFO(rclcpp::get_logger("ArcadeDriver"), "joystick: x=%.2f, y=%.2f, speed: l=%.2f, r=%.2f", joystick_rotate, joystick_drive, left_motor, right_motor); - - auto arcade_msg = drivetrain_msgs::msg::ArcadeSpeed(); - arcade_msg.l = left_motor; - arcade_msg.r = right_motor; - return arcade_msg; + float left_motor; + float right_motor; + + if (joystick_drive >= 0) { + if (joystick_rotate >= 0) { + left_motor = MAX; + right_motor = DIFF; + } else { + left_motor = TOTAL; + right_motor = MAX; + } + } else { + if (joystick_rotate >= 0) { + left_motor = TOTAL; + right_motor = -1 * MAX; + } else { + left_motor = -1 * MAX; + right_motor = DIFF; + } + } + + RCLCPP_INFO( + rclcpp::get_logger("ArcadeDriver"), + "joystick: x=%.2f, y=%.2f, speed: l=%.2f, r=%.2f", + joystick_rotate, + joystick_drive, + left_motor, + right_motor); + + auto arcade_msg = drivetrain_msgs::msg::ArcadeSpeed(); + arcade_msg.l = left_motor; + arcade_msg.r = right_motor; + return arcade_msg; } -int main(int argc, char **argv) { - rclcpp::init(argc, argv); - rclcpp::spin(std::make_shared()); - rclcpp::shutdown(); - return 0; +int main(int argc, char ** argv) +{ + rclcpp::init(argc, argv); + rclcpp::spin(std::make_shared()); + rclcpp::shutdown(); + return 0; } diff --git a/src/robot/bringup_robot/CMakeLists.txt b/src/robot/bringup_robot/CMakeLists.txt index bb4484d..475a06c 100644 --- a/src/robot/bringup_robot/CMakeLists.txt +++ b/src/robot/bringup_robot/CMakeLists.txt @@ -1,3 +1,16 @@ +# Copyright (c) 2025-present WATonomous. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. cmake_minimum_required(VERSION 3.5) project(bringup_robot) diff --git a/src/robot/bringup_robot/launch/robot.launch.py b/src/robot/bringup_robot/launch/robot.launch.py index 749704e..3425961 100644 --- a/src/robot/bringup_robot/launch/robot.launch.py +++ b/src/robot/bringup_robot/launch/robot.launch.py @@ -1,12 +1,27 @@ +# Copyright (c) 2025-present WATonomous. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. from ament_index_python.packages import get_package_share_directory from launch import LaunchDescription -from launch.actions import DeclareLaunchArgument, IncludeLaunchDescription -from launch.substitutions import LaunchConfiguration +from launch.actions import IncludeLaunchDescription from launch_ros.actions import Node from launch.launch_description_sources import PythonLaunchDescriptionSource +from launch.actions import DeclareLaunchArgument +from launch.substitutions import LaunchConfiguration import os + def generate_launch_description(): ld = LaunchDescription() # Begin building a launch description @@ -22,56 +37,51 @@ def generate_launch_description(): #################### Odometry Spoof Node ##################### odometry_spoof_node = Node( - package='odometry_spoof', - name='odometry_spoof', - executable='odometry_spoof', + package="odometry_spoof", + name="odometry_spoof", + executable="odometry_spoof", ) ld.add_action(odometry_spoof_node) #################### RealSense Node ##################### realsense_launch_file = os.path.join( - get_package_share_directory('realsense2_camera'), - 'launch', - 'rs_launch.py' + get_package_share_directory("realsense2_camera"), "launch", "rs_launch.py" ) realsense_launch = IncludeLaunchDescription( PythonLaunchDescriptionSource(realsense_launch_file), - launch_arguments={ - 'pointcloud.enable': 'true', - 'filters': 'spatial' - }.items() + launch_arguments={"pointcloud.enable": "true", "filters": "spatial"}.items(), ) ld.add_action(realsense_launch) #################### Camera Fallback Node ##################### camera_fallback_node = Node( - package='camera_fallback', - name='camera_fallback_node', - executable='camera_fallback_node', + package="camera_fallback", + name="camera_fallback_node", + executable="camera_fallback_node", ) ld.add_action(camera_fallback_node) #################### ArcadeDriver Node ##################### arcade_driver_node = Node( - package='arcade_driver', - name='arcade_driver', - executable='arcade_driver', + package="arcade_driver", + name="arcade_driver", + executable="arcade_driver", ) ld.add_action(arcade_driver_node) #################### MotorSpeedController Node ##################### motor_speed_controller_node = Node( - package='motor_speed_controller', - name='motor_speed_controller', - executable='motor_speed_controller', + package="motor_speed_controller", + name="motor_speed_controller", + executable="motor_speed_controller", ) ld.add_action(motor_speed_controller_node) #################### Object_detection Node ##################### object_detection_node = Node( - package='object_detection', - name='object_detection_node', - executable='object_detection_node', + package="object_detection", + name="object_detection_node", + executable="object_detection_node", ) ld.add_action(object_detection_node) @@ -84,7 +94,7 @@ def generate_launch_description(): parameters=[ { "model_path": LaunchConfiguration("model_path"), - "input_size": 640, # TODO: adjust DEPENDING on model needs 416, 512, etc + "input_size": 640, # TODO: adjust DEPENDING on model needs 416, 512, etc } ], remappings=[("/image", "/sim/realsense1/depth/image")], diff --git a/src/robot/bringup_robot/package.xml b/src/robot/bringup_robot/package.xml index 0ba0df2..d224537 100644 --- a/src/robot/bringup_robot/package.xml +++ b/src/robot/bringup_robot/package.xml @@ -25,4 +25,4 @@ ament_cmake - \ No newline at end of file + diff --git a/src/robot/camera_fallback/CMakeLists.txt b/src/robot/camera_fallback/CMakeLists.txt index ff0a833..1727483 100644 --- a/src/robot/camera_fallback/CMakeLists.txt +++ b/src/robot/camera_fallback/CMakeLists.txt @@ -1,3 +1,16 @@ +# Copyright (c) 2025-present WATonomous. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. cmake_minimum_required(VERSION 3.8) project(camera_fallback) @@ -37,4 +50,4 @@ if(BUILD_TESTING) endif() # Export package dependencies -ament_package() \ No newline at end of file +ament_package() diff --git a/src/robot/camera_fallback/package.xml b/src/robot/camera_fallback/package.xml index 332604c..cbe5049 100644 --- a/src/robot/camera_fallback/package.xml +++ b/src/robot/camera_fallback/package.xml @@ -16,4 +16,4 @@ ament_cmake - \ No newline at end of file + diff --git a/src/robot/camera_fallback/src/camera_fallback_node.cpp b/src/robot/camera_fallback/src/camera_fallback_node.cpp index 5462e76..f25bc49 100644 --- a/src/robot/camera_fallback/src/camera_fallback_node.cpp +++ b/src/robot/camera_fallback/src/camera_fallback_node.cpp @@ -1,28 +1,45 @@ +// Copyright (c) 2025-present WATonomous. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include + #include #include -#include class CameraFallbackNode : public rclcpp::Node { public: CameraFallbackNode() - : Node("camera_fallback_node"), use_real_camera_(false), last_real_msg_time_(0.0), timeout_(30.0) + : Node("camera_fallback_node") + , use_real_camera_(false) + , last_real_msg_time_(0.0) + , timeout_(30.0) { // Publishers unified_pub_ = this->create_publisher("/camera/depth/points", 10); // Subscribers real_sub_ = this->create_subscription( - "/camera/camera/depth/color/points", 10, + "/camera/camera/depth/color/points", + 10, std::bind(&CameraFallbackNode::real_callback, this, std::placeholders::_1)); sim_sub_ = this->create_subscription( - "/sim/realsense1/depth/points", 10, - std::bind(&CameraFallbackNode::sim_callback, this, std::placeholders::_1)); + "/sim/realsense1/depth/points", 10, std::bind(&CameraFallbackNode::sim_callback, this, std::placeholders::_1)); // Timer to check real camera activity timer_ = this->create_wall_timer( - std::chrono::milliseconds(120000), - std::bind(&CameraFallbackNode::check_camera_activity, this)); + std::chrono::milliseconds(120000), std::bind(&CameraFallbackNode::check_camera_activity, this)); } private: @@ -66,4 +83,4 @@ int main(int argc, char * argv[]) rclcpp::spin(std::make_shared()); rclcpp::shutdown(); return 0; -} \ No newline at end of file +} diff --git a/src/robot/control/CMakeLists.txt b/src/robot/control/CMakeLists.txt index 0119109..dce8810 100644 --- a/src/robot/control/CMakeLists.txt +++ b/src/robot/control/CMakeLists.txt @@ -1,3 +1,16 @@ +# Copyright (c) 2025-present WATonomous. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. cmake_minimum_required(VERSION 3.10) project(control) @@ -46,4 +59,4 @@ install(DIRECTORY config DESTINATION share/${PROJECT_NAME}) -ament_package() \ No newline at end of file +ament_package() diff --git a/src/robot/control/config/params.yaml b/src/robot/control/config/params.yaml index 0f334b6..dde97a4 100644 --- a/src/robot/control/config/params.yaml +++ b/src/robot/control/config/params.yaml @@ -1,3 +1,2 @@ # control_node: # ros__parameters: - diff --git a/src/robot/control/include/control/control_core.hpp b/src/robot/control/include/control/control_core.hpp new file mode 100644 index 0000000..2c1b9c2 --- /dev/null +++ b/src/robot/control/include/control/control_core.hpp @@ -0,0 +1,35 @@ +// Copyright (c) 2025-present WATonomous. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef CONTROL_CORE_HPP_ +#define CONTROL_CORE_HPP_ + +#include "rclcpp/rclcpp.hpp" + +namespace robot +{ + +class ControlCore +{ +public: + // Constructor, we pass in the node's RCLCPP logger to enable logging to terminal + explicit ControlCore(const rclcpp::Logger & logger); + +private: + rclcpp::Logger logger_; +}; + +} // namespace robot + +#endif diff --git a/src/robot/control/include/control/control_node.hpp b/src/robot/control/include/control/control_node.hpp new file mode 100644 index 0000000..8fc6eeb --- /dev/null +++ b/src/robot/control/include/control/control_node.hpp @@ -0,0 +1,30 @@ +// Copyright (c) 2025-present WATonomous. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef CONTROL_NODE_HPP_ +#define CONTROL_NODE_HPP_ + +#include "control/control_core.hpp" +#include "rclcpp/rclcpp.hpp" + +class ControlNode : public rclcpp::Node +{ +public: + ControlNode(); + +private: + robot::ControlCore control_; +}; + +#endif diff --git a/src/robot/control/include/control_core.hpp b/src/robot/control/include/control_core.hpp deleted file mode 100644 index ad19ecb..0000000 --- a/src/robot/control/include/control_core.hpp +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef CONTROL_CORE_HPP_ -#define CONTROL_CORE_HPP_ - -#include "rclcpp/rclcpp.hpp" - -namespace robot -{ - -class ControlCore { - public: - // Constructor, we pass in the node's RCLCPP logger to enable logging to terminal - ControlCore(const rclcpp::Logger& logger); - - private: - rclcpp::Logger logger_; -}; - -} - -#endif diff --git a/src/robot/control/include/control_node.hpp b/src/robot/control/include/control_node.hpp deleted file mode 100644 index d47f95b..0000000 --- a/src/robot/control/include/control_node.hpp +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef CONTROL_NODE_HPP_ -#define CONTROL_NODE_HPP_ - -#include "rclcpp/rclcpp.hpp" - -#include "control_core.hpp" - -class ControlNode : public rclcpp::Node { - public: - ControlNode(); - - private: - robot::ControlCore control_; -}; - -#endif diff --git a/src/robot/control/package.xml b/src/robot/control/package.xml index b9b7cd6..7fb2721 100644 --- a/src/robot/control/package.xml +++ b/src/robot/control/package.xml @@ -19,4 +19,4 @@ ament_cmake - \ No newline at end of file + diff --git a/src/robot/control/src/control_core.cpp b/src/robot/control/src/control_core.cpp index c935803..0003719 100644 --- a/src/robot/control/src/control_core.cpp +++ b/src/robot/control/src/control_core.cpp @@ -1,9 +1,24 @@ -#include "control_core.hpp" +// Copyright (c) 2025-present WATonomous. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "control/control_core.hpp" namespace robot { -ControlCore::ControlCore(const rclcpp::Logger& logger) - : logger_(logger) {} +ControlCore::ControlCore(const rclcpp::Logger & logger) +: logger_(logger) +{} -} +} // namespace robot diff --git a/src/robot/control/src/control_node.cpp b/src/robot/control/src/control_node.cpp index c99e200..b560494 100644 --- a/src/robot/control/src/control_node.cpp +++ b/src/robot/control/src/control_node.cpp @@ -1,6 +1,23 @@ -#include "control_node.hpp" +// Copyright (c) 2025-present WATonomous. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. -ControlNode::ControlNode(): Node("control"), control_(robot::ControlCore(this->get_logger())) {} +#include "control/control_node.hpp" + +ControlNode::ControlNode() +: Node("control") +, control_(robot::ControlCore(this->get_logger())) +{} int main(int argc, char ** argv) { diff --git a/src/robot/costmap/CMakeLists.txt b/src/robot/costmap/CMakeLists.txt index 130ebb8..7957026 100644 --- a/src/robot/costmap/CMakeLists.txt +++ b/src/robot/costmap/CMakeLists.txt @@ -1,3 +1,16 @@ +# Copyright (c) 2025-present WATonomous. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. cmake_minimum_required(VERSION 3.10) project(costmap) @@ -42,4 +55,4 @@ install(DIRECTORY config DESTINATION share/${PROJECT_NAME}) -ament_package() \ No newline at end of file +ament_package() diff --git a/src/robot/costmap/config/params.yaml b/src/robot/costmap/config/params.yaml index 544d49f..1833ec5 100644 --- a/src/robot/costmap/config/params.yaml +++ b/src/robot/costmap/config/params.yaml @@ -1,3 +1,2 @@ # costmap_node: # ros__parameters: - diff --git a/src/robot/costmap/include/costmap/costmap_core.hpp b/src/robot/costmap/include/costmap/costmap_core.hpp new file mode 100644 index 0000000..e583b2b --- /dev/null +++ b/src/robot/costmap/include/costmap/costmap_core.hpp @@ -0,0 +1,35 @@ +// Copyright (c) 2025-present WATonomous. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef COSTMAP_CORE_HPP_ +#define COSTMAP_CORE_HPP_ + +#include "rclcpp/rclcpp.hpp" + +namespace robot +{ + +class CostmapCore +{ +public: + // Constructor, we pass in the node's RCLCPP logger to enable logging to terminal + explicit CostmapCore(const rclcpp::Logger & logger); + +private: + rclcpp::Logger logger_; +}; + +} // namespace robot + +#endif diff --git a/src/robot/costmap/include/costmap/costmap_node.hpp b/src/robot/costmap/include/costmap/costmap_node.hpp new file mode 100644 index 0000000..2080a1c --- /dev/null +++ b/src/robot/costmap/include/costmap/costmap_node.hpp @@ -0,0 +1,30 @@ +// Copyright (c) 2025-present WATonomous. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef COSTMAP_NODE_HPP_ +#define COSTMAP_NODE_HPP_ + +#include "costmap/costmap_core.hpp" +#include "rclcpp/rclcpp.hpp" + +class CostmapNode : public rclcpp::Node +{ +public: + CostmapNode(); + +private: + robot::CostmapCore costmap_; +}; + +#endif diff --git a/src/robot/costmap/include/costmap_core.hpp b/src/robot/costmap/include/costmap_core.hpp deleted file mode 100644 index b8baa59..0000000 --- a/src/robot/costmap/include/costmap_core.hpp +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef COSTMAP_CORE_HPP_ -#define COSTMAP_CORE_HPP_ - -#include "rclcpp/rclcpp.hpp" - -namespace robot -{ - -class CostmapCore { - public: - // Constructor, we pass in the node's RCLCPP logger to enable logging to terminal - explicit CostmapCore(const rclcpp::Logger& logger); - - private: - rclcpp::Logger logger_; - -}; - -} - -#endif \ No newline at end of file diff --git a/src/robot/costmap/include/costmap_node.hpp b/src/robot/costmap/include/costmap_node.hpp deleted file mode 100644 index df7d5f1..0000000 --- a/src/robot/costmap/include/costmap_node.hpp +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef COSTMAP_NODE_HPP_ -#define COSTMAP_NODE_HPP_ - -#include "rclcpp/rclcpp.hpp" - -#include "costmap_core.hpp" - -class CostmapNode : public rclcpp::Node { - public: - CostmapNode(); - - private: - robot::CostmapCore costmap_; -}; - -#endif \ No newline at end of file diff --git a/src/robot/costmap/package.xml b/src/robot/costmap/package.xml index 4651c55..2abc8b5 100644 --- a/src/robot/costmap/package.xml +++ b/src/robot/costmap/package.xml @@ -19,4 +19,4 @@ ament_cmake - \ No newline at end of file + diff --git a/src/robot/costmap/src/costmap_core.cpp b/src/robot/costmap/src/costmap_core.cpp index 2fd0c92..e12a494 100644 --- a/src/robot/costmap/src/costmap_core.cpp +++ b/src/robot/costmap/src/costmap_core.cpp @@ -1,8 +1,24 @@ -#include "costmap_core.hpp" +// Copyright (c) 2025-present WATonomous. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "costmap/costmap_core.hpp" namespace robot { -CostmapCore::CostmapCore(const rclcpp::Logger& logger) : logger_(logger) {} +CostmapCore::CostmapCore(const rclcpp::Logger & logger) +: logger_(logger) +{} -} \ No newline at end of file +} // namespace robot diff --git a/src/robot/costmap/src/costmap_node.cpp b/src/robot/costmap/src/costmap_node.cpp index 33a47a7..163fe33 100644 --- a/src/robot/costmap/src/costmap_node.cpp +++ b/src/robot/costmap/src/costmap_node.cpp @@ -1,9 +1,26 @@ +// Copyright (c) 2025-present WATonomous. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "costmap/costmap_node.hpp" + #include #include -#include "costmap_node.hpp" - -CostmapNode::CostmapNode() : Node("costmap"), costmap_(robot::CostmapCore(this->get_logger())) {} +CostmapNode::CostmapNode() +: Node("costmap") +, costmap_(robot::CostmapCore(this->get_logger())) +{} int main(int argc, char ** argv) { @@ -11,4 +28,4 @@ int main(int argc, char ** argv) rclcpp::spin(std::make_shared()); rclcpp::shutdown(); return 0; -} \ No newline at end of file +} diff --git a/src/robot/map_memory/CMakeLists.txt b/src/robot/map_memory/CMakeLists.txt index 0445870..9807196 100644 --- a/src/robot/map_memory/CMakeLists.txt +++ b/src/robot/map_memory/CMakeLists.txt @@ -1,3 +1,16 @@ +# Copyright (c) 2025-present WATonomous. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. cmake_minimum_required(VERSION 3.10) project(map_memory) @@ -25,7 +38,7 @@ add_library(map_memory_lib target_include_directories(map_memory_lib PUBLIC include) # Add ROS2 dependencies required by package -ament_target_dependencies(map_memory_lib +ament_target_dependencies(map_memory_lib rclcpp ) diff --git a/src/robot/map_memory/config/params.yaml b/src/robot/map_memory/config/params.yaml index 282ca85..0808832 100644 --- a/src/robot/map_memory/config/params.yaml +++ b/src/robot/map_memory/config/params.yaml @@ -1,3 +1,2 @@ # map_memory_node: # ros__parameters: - diff --git a/src/robot/map_memory/include/map_memory/map_memory_core.hpp b/src/robot/map_memory/include/map_memory/map_memory_core.hpp new file mode 100644 index 0000000..2186aee --- /dev/null +++ b/src/robot/map_memory/include/map_memory/map_memory_core.hpp @@ -0,0 +1,34 @@ +// Copyright (c) 2025-present WATonomous. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef MAP_MEMORY_CORE_HPP_ +#define MAP_MEMORY_CORE_HPP_ + +#include "rclcpp/rclcpp.hpp" + +namespace robot +{ + +class MapMemoryCore +{ +public: + explicit MapMemoryCore(const rclcpp::Logger & logger); + +private: + rclcpp::Logger logger_; +}; + +} // namespace robot + +#endif diff --git a/src/robot/map_memory/include/map_memory/map_memory_node.hpp b/src/robot/map_memory/include/map_memory/map_memory_node.hpp new file mode 100644 index 0000000..6724402 --- /dev/null +++ b/src/robot/map_memory/include/map_memory/map_memory_node.hpp @@ -0,0 +1,30 @@ +// Copyright (c) 2025-present WATonomous. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef MAP_MEMORY_NODE_HPP_ +#define MAP_MEMORY_NODE_HPP_ + +#include "map_memory/map_memory_core.hpp" +#include "rclcpp/rclcpp.hpp" + +class MapMemoryNode : public rclcpp::Node +{ +public: + MapMemoryNode(); + +private: + robot::MapMemoryCore map_memory_; +}; + +#endif diff --git a/src/robot/map_memory/include/map_memory_core.hpp b/src/robot/map_memory/include/map_memory_core.hpp deleted file mode 100644 index 2610b8f..0000000 --- a/src/robot/map_memory/include/map_memory_core.hpp +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef MAP_MEMORY_CORE_HPP_ -#define MAP_MEMORY_CORE_HPP_ - -#include "rclcpp/rclcpp.hpp" - -namespace robot -{ - -class MapMemoryCore { - public: - explicit MapMemoryCore(const rclcpp::Logger& logger); - - private: - rclcpp::Logger logger_; -}; - -} - -#endif diff --git a/src/robot/map_memory/include/map_memory_node.hpp b/src/robot/map_memory/include/map_memory_node.hpp deleted file mode 100644 index e55a567..0000000 --- a/src/robot/map_memory/include/map_memory_node.hpp +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef MAP_MEMORY_NODE_HPP_ -#define MAP_MEMORY_NODE_HPP_ - -#include "rclcpp/rclcpp.hpp" - -#include "map_memory_core.hpp" - -class MapMemoryNode : public rclcpp::Node { - public: - MapMemoryNode(); - - private: - robot::MapMemoryCore map_memory_; -}; - -#endif diff --git a/src/robot/map_memory/package.xml b/src/robot/map_memory/package.xml index 9cc4b5f..748c2da 100644 --- a/src/robot/map_memory/package.xml +++ b/src/robot/map_memory/package.xml @@ -19,4 +19,4 @@ ament_cmake - \ No newline at end of file + diff --git a/src/robot/map_memory/src/map_memory_core.cpp b/src/robot/map_memory/src/map_memory_core.cpp index 8a7dee9..7c6c230 100644 --- a/src/robot/map_memory/src/map_memory_core.cpp +++ b/src/robot/map_memory/src/map_memory_core.cpp @@ -1,9 +1,24 @@ -#include "map_memory_core.hpp" +// Copyright (c) 2025-present WATonomous. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "map_memory/map_memory_core.hpp" namespace robot { -MapMemoryCore::MapMemoryCore(const rclcpp::Logger& logger) - : logger_(logger) {} +MapMemoryCore::MapMemoryCore(const rclcpp::Logger & logger) +: logger_(logger) +{} -} +} // namespace robot diff --git a/src/robot/map_memory/src/map_memory_node.cpp b/src/robot/map_memory/src/map_memory_node.cpp index 1ce7774..fa58e9d 100644 --- a/src/robot/map_memory/src/map_memory_node.cpp +++ b/src/robot/map_memory/src/map_memory_node.cpp @@ -1,6 +1,23 @@ -#include "map_memory_node.hpp" +// Copyright (c) 2025-present WATonomous. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. -MapMemoryNode::MapMemoryNode() : Node("map_memory"), map_memory_(robot::MapMemoryCore(this->get_logger())) {} +#include "map_memory/map_memory_node.hpp" + +MapMemoryNode::MapMemoryNode() +: Node("map_memory") +, map_memory_(robot::MapMemoryCore(this->get_logger())) +{} int main(int argc, char ** argv) { diff --git a/src/robot/motor_speed_controller/CMakeLists.txt b/src/robot/motor_speed_controller/CMakeLists.txt index 9bcd7d1..9f91292 100644 --- a/src/robot/motor_speed_controller/CMakeLists.txt +++ b/src/robot/motor_speed_controller/CMakeLists.txt @@ -1,3 +1,16 @@ +# Copyright (c) 2025-present WATonomous. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. cmake_minimum_required(VERSION 3.10) project(motor_speed_controller) diff --git a/src/robot/motor_speed_controller/include/motor_speed_controller.hpp b/src/robot/motor_speed_controller/include/motor_speed_controller.hpp deleted file mode 100644 index 8226d0f..0000000 --- a/src/robot/motor_speed_controller/include/motor_speed_controller.hpp +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef MOTOR_SPEED_CONTROLLER_NODE_HPP_ -#define MOTOR_SPEED_CONTROLLER_NODE_HPP_ - -#include -#include "drivetrain_msgs/msg/arcade_speed.hpp" -#include "drivetrain_msgs/msg/motor_speeds.hpp" -#include -#include - -class MotorSpeedController : public rclcpp::Node { - public: - MotorSpeedController(); - - private: - // subscriber to arcade speed topic (/arcade_speed) - rclcpp::Subscription::SharedPtr arcade_sub_; - - // publishers to set motor speeds - rclcpp::Publisher::SharedPtr motor_speeds_pub_; - rclcpp::Publisher::SharedPtr odrive_pub_; - - // functions to compute motor speeds - void arcade_callback(const drivetrain_msgs::msg::ArcadeSpeed arcade_msg); - drivetrain_msgs::msg::MotorSpeeds compute_motor_speeds(const float arcade_l, const float arcade_r); - - void publish_speeds_odrive(drivetrain_msgs::msg::MotorSpeeds speeds); - const nlohmann::json odrive_speed_req_json = { - {"Stage", "run"}, - {"Type", "request"}, - {"Target", "Drivetrain"}, - {"Command", "Set_Input_Vel"} - }; - const float VEL_SCALER = 40; -}; - -#endif diff --git a/src/robot/motor_speed_controller/include/motor_speed_controller/motor_speed_controller.hpp b/src/robot/motor_speed_controller/include/motor_speed_controller/motor_speed_controller.hpp new file mode 100644 index 0000000..d5f4d70 --- /dev/null +++ b/src/robot/motor_speed_controller/include/motor_speed_controller/motor_speed_controller.hpp @@ -0,0 +1,48 @@ +// Copyright (c) 2025-present WATonomous. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef MOTOR_SPEED_CONTROLLER_NODE_HPP_ +#define MOTOR_SPEED_CONTROLLER_NODE_HPP_ + +#include +#include +#include + +#include "drivetrain_msgs/msg/arcade_speed.hpp" +#include "drivetrain_msgs/msg/motor_speeds.hpp" + +class MotorSpeedController : public rclcpp::Node +{ +public: + MotorSpeedController(); + +private: + // subscriber to arcade speed topic (/arcade_speed) + rclcpp::Subscription::SharedPtr arcade_sub_; + + // publishers to set motor speeds + rclcpp::Publisher::SharedPtr motor_speeds_pub_; + rclcpp::Publisher::SharedPtr odrive_pub_; + + // functions to compute motor speeds + void arcade_callback(const drivetrain_msgs::msg::ArcadeSpeed arcade_msg); + drivetrain_msgs::msg::MotorSpeeds compute_motor_speeds(const float arcade_l, const float arcade_r); + + void publish_speeds_odrive(drivetrain_msgs::msg::MotorSpeeds speeds); + const nlohmann::json odrive_speed_req_json = { + {"Stage", "run"}, {"Type", "request"}, {"Target", "Drivetrain"}, {"Command", "Set_Input_Vel"}}; + const float VEL_SCALER = 40; +}; + +#endif diff --git a/src/robot/motor_speed_controller/include/nlohmann/json.hpp b/src/robot/motor_speed_controller/include/nlohmann/json.hpp index 919b5fc..4c752b8 100644 --- a/src/robot/motor_speed_controller/include/nlohmann/json.hpp +++ b/src/robot/motor_speed_controller/include/nlohmann/json.hpp @@ -1,3 +1,17 @@ +// Copyright (c) 2025-present WATonomous. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + // __ _____ _____ _____ // __| | __| | | | JSON for Modern C++ // | | |__ | | | | | | version 3.12.0 @@ -18,18 +32,18 @@ #ifndef INCLUDE_NLOHMANN_JSON_HPP_ #define INCLUDE_NLOHMANN_JSON_HPP_ -#include // all_of, find, for_each -#include // nullptr_t, ptrdiff_t, size_t -#include // hash, less -#include // initializer_list +#include // all_of, find, for_each +#include // nullptr_t, ptrdiff_t, size_t +#include // hash, less +#include // initializer_list #ifndef JSON_NO_IO - #include // istream, ostream + #include // istream, ostream #endif // JSON_NO_IO -#include // random_access_iterator_tag -#include // unique_ptr -#include // string, stoi, to_string -#include // declval, forward, move, pair, swap -#include // vector +#include // random_access_iterator_tag +#include // unique_ptr +#include // string, stoi, to_string +#include // declval, forward, move, pair, swap +#include // vector // #include // __ _____ _____ _____ @@ -40,8 +54,6 @@ // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann // SPDX-License-Identifier: MIT - - #include // #include @@ -53,107 +65,98 @@ // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann // SPDX-License-Identifier: MIT - - // This file contains all macro definitions affecting or depending on the ABI #ifndef JSON_SKIP_LIBRARY_VERSION_CHECK - #if defined(NLOHMANN_JSON_VERSION_MAJOR) && defined(NLOHMANN_JSON_VERSION_MINOR) && defined(NLOHMANN_JSON_VERSION_PATCH) - #if NLOHMANN_JSON_VERSION_MAJOR != 3 || NLOHMANN_JSON_VERSION_MINOR != 12 || NLOHMANN_JSON_VERSION_PATCH != 0 - #warning "Already included a different version of the library!" - #endif + #if defined(NLOHMANN_JSON_VERSION_MAJOR) && defined(NLOHMANN_JSON_VERSION_MINOR) && \ + defined(NLOHMANN_JSON_VERSION_PATCH) + #if NLOHMANN_JSON_VERSION_MAJOR != 3 || NLOHMANN_JSON_VERSION_MINOR != 12 || NLOHMANN_JSON_VERSION_PATCH != 0 + #warning "Already included a different version of the library!" #endif + #endif #endif -#define NLOHMANN_JSON_VERSION_MAJOR 3 // NOLINT(modernize-macro-to-enum) +#define NLOHMANN_JSON_VERSION_MAJOR 3 // NOLINT(modernize-macro-to-enum) #define NLOHMANN_JSON_VERSION_MINOR 12 // NOLINT(modernize-macro-to-enum) -#define NLOHMANN_JSON_VERSION_PATCH 0 // NOLINT(modernize-macro-to-enum) +#define NLOHMANN_JSON_VERSION_PATCH 0 // NOLINT(modernize-macro-to-enum) #ifndef JSON_DIAGNOSTICS - #define JSON_DIAGNOSTICS 0 + #define JSON_DIAGNOSTICS 0 #endif #ifndef JSON_DIAGNOSTIC_POSITIONS - #define JSON_DIAGNOSTIC_POSITIONS 0 + #define JSON_DIAGNOSTIC_POSITIONS 0 #endif #ifndef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON - #define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 0 + #define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 0 #endif #if JSON_DIAGNOSTICS - #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS _diag + #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS _diag #else - #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS + #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS #endif #if JSON_DIAGNOSTIC_POSITIONS - #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTIC_POSITIONS _dp + #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTIC_POSITIONS _dp #else - #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTIC_POSITIONS + #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTIC_POSITIONS #endif #if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON - #define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON _ldvcmp + #define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON _ldvcmp #else - #define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON + #define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON #endif #ifndef NLOHMANN_JSON_NAMESPACE_NO_VERSION - #define NLOHMANN_JSON_NAMESPACE_NO_VERSION 0 + #define NLOHMANN_JSON_NAMESPACE_NO_VERSION 0 #endif // Construct the namespace ABI tags component -#define NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b, c) json_abi ## a ## b ## c -#define NLOHMANN_JSON_ABI_TAGS_CONCAT(a, b, c) \ - NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b, c) +#define NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b, c) json_abi##a##b##c +#define NLOHMANN_JSON_ABI_TAGS_CONCAT(a, b, c) NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b, c) -#define NLOHMANN_JSON_ABI_TAGS \ - NLOHMANN_JSON_ABI_TAGS_CONCAT( \ - NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS, \ - NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON, \ - NLOHMANN_JSON_ABI_TAG_DIAGNOSTIC_POSITIONS) +#define NLOHMANN_JSON_ABI_TAGS \ + NLOHMANN_JSON_ABI_TAGS_CONCAT( \ + NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS, \ + NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON, \ + NLOHMANN_JSON_ABI_TAG_DIAGNOSTIC_POSITIONS) // Construct the namespace version component -#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) \ - _v ## major ## _ ## minor ## _ ## patch +#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) _v##major##_##minor##_##patch #define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(major, minor, patch) \ - NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) + NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) #if NLOHMANN_JSON_NAMESPACE_NO_VERSION -#define NLOHMANN_JSON_NAMESPACE_VERSION + #define NLOHMANN_JSON_NAMESPACE_VERSION #else -#define NLOHMANN_JSON_NAMESPACE_VERSION \ - NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(NLOHMANN_JSON_VERSION_MAJOR, \ - NLOHMANN_JSON_VERSION_MINOR, \ - NLOHMANN_JSON_VERSION_PATCH) + #define NLOHMANN_JSON_NAMESPACE_VERSION \ + NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT( \ + NLOHMANN_JSON_VERSION_MAJOR, NLOHMANN_JSON_VERSION_MINOR, NLOHMANN_JSON_VERSION_PATCH) #endif // Combine namespace components -#define NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b) a ## b -#define NLOHMANN_JSON_NAMESPACE_CONCAT(a, b) \ - NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b) +#define NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b) a##b +#define NLOHMANN_JSON_NAMESPACE_CONCAT(a, b) NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b) #ifndef NLOHMANN_JSON_NAMESPACE -#define NLOHMANN_JSON_NAMESPACE \ - nlohmann::NLOHMANN_JSON_NAMESPACE_CONCAT( \ - NLOHMANN_JSON_ABI_TAGS, \ - NLOHMANN_JSON_NAMESPACE_VERSION) + #define NLOHMANN_JSON_NAMESPACE \ + nlohmann::NLOHMANN_JSON_NAMESPACE_CONCAT(NLOHMANN_JSON_ABI_TAGS, NLOHMANN_JSON_NAMESPACE_VERSION) #endif #ifndef NLOHMANN_JSON_NAMESPACE_BEGIN -#define NLOHMANN_JSON_NAMESPACE_BEGIN \ - namespace nlohmann \ - { \ - inline namespace NLOHMANN_JSON_NAMESPACE_CONCAT( \ - NLOHMANN_JSON_ABI_TAGS, \ - NLOHMANN_JSON_NAMESPACE_VERSION) \ + #define NLOHMANN_JSON_NAMESPACE_BEGIN \ + namespace nlohmann \ + { \ + inline namespace NLOHMANN_JSON_NAMESPACE_CONCAT(NLOHMANN_JSON_ABI_TAGS, NLOHMANN_JSON_NAMESPACE_VERSION) \ { #endif #ifndef NLOHMANN_JSON_NAMESPACE_END -#define NLOHMANN_JSON_NAMESPACE_END \ - } /* namespace (inline namespace) NOLINT(readability/namespace) */ \ + #define NLOHMANN_JSON_NAMESPACE_END \ + } /* namespace (inline namespace) NOLINT(readability/namespace) */ \ } // namespace nlohmann #endif @@ -166,19 +169,17 @@ // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann // SPDX-License-Identifier: MIT - - -#include // transform -#include // array -#include // forward_list -#include // inserter, front_inserter, end -#include // map -#include // string -#include // tuple, make_tuple -#include // is_arithmetic, is_same, is_enum, underlying_type, is_convertible -#include // unordered_map -#include // pair, declval -#include // valarray +#include // transform +#include // array +#include // forward_list +#include // inserter, front_inserter, end +#include // map +#include // string +#include // tuple, make_tuple +#include // is_arithmetic, is_same, is_enum, underlying_type, is_convertible +#include // unordered_map +#include // pair, declval +#include // valarray // #include // __ _____ _____ _____ @@ -189,16 +190,14 @@ // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann // SPDX-License-Identifier: MIT - - -#include // nullptr_t -#include // exception +#include // nullptr_t +#include // exception #if JSON_DIAGNOSTICS - #include // accumulate + #include // accumulate #endif -#include // runtime_error -#include // to_string -#include // vector +#include // runtime_error +#include // to_string +#include // vector // #include // __ _____ _____ _____ @@ -209,12 +208,10 @@ // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann // SPDX-License-Identifier: MIT - - -#include // array -#include // size_t -#include // uint8_t -#include // string +#include // array +#include // size_t +#include // uint8_t +#include // string // #include // __ _____ _____ _____ @@ -225,9 +222,7 @@ // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann // SPDX-License-Identifier: MIT - - -#include // declval, pair +#include // declval, pair // #include // __ _____ _____ _____ // __| | __| | | | JSON for Modern C++ @@ -237,8 +232,6 @@ // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann // SPDX-License-Identifier: MIT - - #include // #include @@ -250,85 +243,84 @@ // SPDX-FileCopyrightText: 2013 - 2025 Niels Lohmann // SPDX-License-Identifier: MIT - - // #include - NLOHMANN_JSON_NAMESPACE_BEGIN + namespace detail { -template struct make_void +template +struct make_void { - using type = void; + using type = void; }; -template using void_t = typename make_void::type; + +template +using void_t = typename make_void::type; } // namespace detail -NLOHMANN_JSON_NAMESPACE_END +NLOHMANN_JSON_NAMESPACE_END NLOHMANN_JSON_NAMESPACE_BEGIN + namespace detail { // https://en.cppreference.com/w/cpp/experimental/is_detected struct nonesuch { - nonesuch() = delete; - ~nonesuch() = delete; - nonesuch(nonesuch const&) = delete; - nonesuch(nonesuch const&&) = delete; - void operator=(nonesuch const&) = delete; - void operator=(nonesuch&&) = delete; + nonesuch() = delete; + ~nonesuch() = delete; + nonesuch(nonesuch const &) = delete; + nonesuch(nonesuch const &&) = delete; + void operator=(nonesuch const &) = delete; + void operator=(nonesuch &&) = delete; }; -template class Op, - class... Args> +template class Op, class... Args> struct detector { - using value_t = std::false_type; - using type = Default; + using value_t = std::false_type; + using type = Default; }; -template class Op, class... Args> +template class Op, class... Args> struct detector>, Op, Args...> { - using value_t = std::true_type; - using type = Op; + using value_t = std::true_type; + using type = Op; }; -template class Op, class... Args> +template