diff --git a/.env b/.env new file mode 100644 index 000000000..958a6594d --- /dev/null +++ b/.env @@ -0,0 +1,2 @@ +CONTAINER_USER=ubuntu +CONTAINER_HOME=/home/ubuntu \ No newline at end of file diff --git a/.github/workflows/update-image.yml b/.github/workflows/update-image.yml new file mode 100644 index 000000000..435d3f461 --- /dev/null +++ b/.github/workflows/update-image.yml @@ -0,0 +1,51 @@ +name: Build and Push RMCS Images + +on: + workflow_dispatch: + push: + paths: + - 'Dockerfile' + branches: + - main + +jobs: + build-and-push: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Set up SSH keys + run: | + mkdir -p .ssh + chmod 700 .ssh + echo "${{ secrets.CONTAINER_ID_RSA }}" > .ssh/id_rsa + echo "${{ secrets.CONTAINER_ID_RSA_PUB }}" > .ssh/id_rsa.pub + chmod 600 .ssh/id_rsa + chmod 644 .ssh/id_rsa.pub + + - name: Build and push rmcs-develop:latest + uses: docker/build-push-action@v6 + with: + context: . + push: true + target: rmcs-develop + tags: qzhhhi/rmcs-develop:latest + + - name: Build and push rmcs-runtime:latest + uses: docker/build-push-action@v6 + with: + context: . + push: true + target: rmcs-runtime + tags: qzhhhi/rmcs-runtime:latest diff --git a/.gitmodules b/.gitmodules index 1938ee6ef..d4d71be28 100644 --- a/.gitmodules +++ b/.gitmodules @@ -9,4 +9,4 @@ url = https://github.com/Alliance-Algorithm/ros2-hikcamera.git [submodule "rmcs_ws/src/serial"] path = rmcs_ws/src/serial - url = git@github.com:Alliance-Algorithm/ros2-serial.git + url = https://github.com/Alliance-Algorithm/ros2-serial.git diff --git a/.script/attach-remote b/.script/attach-remote index b249b943a..5f93bc03e 100755 --- a/.script/attach-remote +++ b/.script/attach-remote @@ -1,4 +1,4 @@ -#! /bin/bash +#!/bin/bash # if arg[1] == "-r" if [ "$1" == "-r" ]; then diff --git a/.script/build-rmcs b/.script/build-rmcs index 08d7198ed..2c24a7ed8 100755 --- a/.script/build-rmcs +++ b/.script/build-rmcs @@ -1,7 +1,60 @@ -#! /bin/bash +#!/bin/bash source /opt/ros/jazzy/setup.bash -cd /workspaces/RMCS/rmcs_ws +: "${RMCS_PATH:=/workspaces/RMCS}" -colcon build --symlink-install --merge-install +if [[ ! -d "${RMCS_PATH}/rmcs_ws" ]]; then + echo "> ERROR: Workspace not found: ${RMCS_PATH}/rmcs_ws" + exit 1 +fi + +cd "${RMCS_PATH}"/rmcs_ws || exit 1 + +[[ -x /opt/cmake/bin/cmake ]] && + export PATH="/opt/cmake/bin:$PATH" + +cmake_toolchain_args=() +event_handlers_args=() + +if [[ "${RMCS_USE_LLVM}" == "ON" ]]; then + missing_tools=() + for tool in clang clang++ llvm-ar llvm-ranlib ld.lld ninja; do + if ! command -v "${tool}" &>/dev/null; then + missing_tools+=("${tool}") + fi + done + + if ((${#missing_tools[@]} > 0)); then + echo "> ERROR: LLVM toolchain is required when RMCS_USE_LLVM=ON." + echo "> Missing tools: ${missing_tools[*]}" + echo "> Install the missing tools, or set RMCS_USE_LLVM=OFF to build with GCC." + exit 1 + fi + + echo "> Compiling With LLVM ToolChain" + export CC=clang + export CXX=clang++ + cmake_toolchain_args=( + "-GNinja" + "-DCMAKE_MESSAGE_LOG_LEVEL=ERROR" + "-DCMAKE_EXE_LINKER_FLAGS=-fuse-ld=lld" + "-DCMAKE_SHARED_LINKER_FLAGS=-fuse-ld=lld" + "-DCMAKE_AR=$(command -v llvm-ar)" + "-DCMAKE_RANLIB=$(command -v llvm-ranlib)" + ) + event_handlers_args=( + --event-handlers console_cohesion+ + ) +fi + +colcon_args=( + --symlink-install --merge-install + "${event_handlers_args[@]}" +) +cmake_args=( + "${cmake_toolchain_args[@]}" +) + +CLICOLOR_FORCE=1 NINJA_STATUS="" \ + colcon build "${colcon_args[@]}" "$@" --cmake-args "${cmake_args[@]}" diff --git a/.script/clean-rmcs b/.script/clean-rmcs index cab270198..4c1aa6a60 100755 --- a/.script/clean-rmcs +++ b/.script/clean-rmcs @@ -1,3 +1,13 @@ -#! /bin/bash +#!/bin/bash -rm -rf /workspaces/RMCS/rmcs_ws/build /workspaces/RMCS/rmcs_ws/install /workspaces/RMCS/rmcs_ws/log \ No newline at end of file +: "${RMCS_PATH:=/workspaces/RMCS}" + +if [[ -z "${RMCS_PATH}" || "${RMCS_PATH}" == "/" ]]; then + echo "Invalid RMCS_PATH: '${RMCS_PATH}'" + exit 1 +fi + +rm -rf -- \ + "${RMCS_PATH}/rmcs_ws/build" \ + "${RMCS_PATH}/rmcs_ws/install" \ + "${RMCS_PATH}/rmcs_ws/log" diff --git a/.script/complete/_build-rmcs b/.script/complete/_build-rmcs new file mode 100644 index 000000000..1b5b5894b --- /dev/null +++ b/.script/complete/_build-rmcs @@ -0,0 +1,51 @@ +#compdef build-rmcs + +local _comp_func="${_comps[colcon]}" + +if [[ -z "${_comp_func}" ]]; then + if (( $+functions[_python_argcomplete] )); then + _comp_func="_python_argcomplete" + elif (( $+functions[_colcon] )); then + _comp_func="_colcon" + else + _message "colcon completion not found. Please source colcon completion setup." + return 1 + fi +fi + +if [[ "${_comp_func}" == "_python_argcomplete" ]]; then + local IFS=$'\013' + local -a completions + local _comp_line _comp_point + + _comp_line="colcon build${BUFFER#build-rmcs}" + _comp_point=$((CURSOR + 2)) + + completions=($(IFS="$IFS" \ + COMP_LINE="${_comp_line}" \ + COMP_POINT="${_comp_point}" \ + _ARGCOMPLETE=1 \ + _ARGCOMPLETE_SHELL="zsh" \ + _ARGCOMPLETE_SUPPRESS_SPACE=1 \ + __python_argcomplete_run colcon)) + + _describe colcon completions -o nosort + return 0 +fi + +local -a _orig_words +local _orig_current + +_orig_words=("${words[@]}") +_orig_current=${CURRENT} + +words=(colcon build "${_orig_words[@]:1}") +CURRENT=$((_orig_current + 1)) + +"${_comp_func}" "$@" +local status=$? + +words=("${_orig_words[@]}") +CURRENT=${_orig_current} + +return $status diff --git a/.script/complete/_play-autoaim b/.script/complete/_play-autoaim new file mode 100644 index 000000000..092bc9bb2 --- /dev/null +++ b/.script/complete/_play-autoaim @@ -0,0 +1,7 @@ +#compdef play-autoaim + +_arguments \ + '--user[Remote username]:username:' \ + '--remote[Pull SDP from device into container]' \ + '--no-copy[Skip copy from container to host]' \ + '--ip[IP address of monitor host]:ip:' diff --git a/.script/complete/_set-remote b/.script/complete/_set-remote new file mode 100644 index 000000000..9cbc253be --- /dev/null +++ b/.script/complete/_set-remote @@ -0,0 +1,22 @@ +#compdef set-remote + +_remote_hosts() { + local hosts=( + "169.254.233.233" + "alliance-sentry.local" + "alliance-infantry.local" + "alliance-hero.local" + ) + + # Extract recently used HostName from ~/.ssh/config + if [[ -f ~/.ssh/config ]]; then + local extracted + extracted=(${(f)"$(grep -A1 'Host remote' ~/.ssh/config | grep HostName | awk '{print $2}')"}) + hosts+=(${extracted}) + fi + + compadd -- $hosts +} + +_arguments \ + '1:Remote host address:_remote_hosts' diff --git a/.script/foxglove b/.script/foxglove new file mode 100755 index 000000000..4181a4a33 --- /dev/null +++ b/.script/foxglove @@ -0,0 +1,5 @@ +#!/bin/bash + +source ~/env_setup.bash + +ros2 launch foxglove_bridge foxglove_bridge_launch.xml port:=8765 diff --git a/.script/host/rmcs b/.script/host/rmcs new file mode 100755 index 000000000..0b65f9322 --- /dev/null +++ b/.script/host/rmcs @@ -0,0 +1,96 @@ +#!/bin/bash + +set -euo pipefail + +readonly DEVELOPER_NAME="ubuntu" +readonly NVIM_PATH="/opt/nvim-linux-x86_64/bin/nvim" +readonly NVIM_PORT=6666 +readonly NVIM_HOST="localhost" + +function show_help() { + local project_dir="$1" + local service="$2" + echo "Usage: $(basename "$0") [path] [zsh|n|nvim|neovide|vim|ide]" + echo " Project dir: $project_dir" + echo " Service: $service" +} + +function rmcs_zsh() { + local service="$1" + echo "Starting and entering container..." + docker compose up -d + docker compose exec "$service" zsh +} + +function rmcs_nvim() { + local service="$1" + local timeout=10 + local success=0 + local port=$NVIM_PORT + + echo "Starting container..." + docker compose up -d + + echo "Checking available port and starting nvim headless server..." + while nc -z "$NVIM_HOST" "$port" 2>/dev/null; do + echo "Port $port is occupied, trying next..." + port=$((port + 1)) + done + + echo "Starting nvim server on port $port..." + docker compose exec -u "$DEVELOPER_NAME" -d "$service" \ + "$NVIM_PATH" --headless --listen "$NVIM_HOST:$port" + + for i in $(seq 1 $timeout); do + if nc -z "$NVIM_HOST" "$port" 2>/dev/null; then + echo "nvim server started on port $port" + success=1 + break + fi + echo "Waiting for nvim server to start... ($i/$timeout)" + sleep 1 + done + + if [ $success -eq 1 ]; then + echo "Starting neovide..." + nohup neovide --server="$NVIM_HOST:$port" >/dev/null 2>&1 & + else + echo "nvim server failed to start within $timeout seconds, neovide not launched" + exit 1 + fi +} + +function main() { + local project_dir command + + if [ -d "${1:-}" ]; then + project_dir="$(cd "$1" && pwd)" + command="${2:-}" + else + project_dir="$(pwd)" + command="${1:-}" + fi + + cd "$project_dir" || exit 1 + + if [ ! -f "docker-compose.yml" ]; then + echo "Error: docker-compose.yml not found in current directory" + exit 1 + fi + + local service="rmcs-develop" + + case "$command" in + zsh) + rmcs_zsh "$service" + ;; + n | nvim | neovide | vim | ide) + rmcs_nvim "$service" + ;; + *) + show_help "$project_dir" "$service" + ;; + esac +} + +main "$@" diff --git a/.script/launch-rmcs b/.script/launch-rmcs index c9848811d..26e9ffe34 100755 --- a/.script/launch-rmcs +++ b/.script/launch-rmcs @@ -1,4 +1,4 @@ -#! /bin/bash +#!/bin/bash source ~/env_setup.bash diff --git a/.script/play-autoaim b/.script/play-autoaim new file mode 100755 index 000000000..c86b6cc79 --- /dev/null +++ b/.script/play-autoaim @@ -0,0 +1,85 @@ +#!/bin/bash + +set -euo pipefail + +MONITOR_USER="" +MONITOR_PLAYER="vlc" +MONITOR_HOST="localhost" + +SDP_PATH="/tmp/auto_aim.sdp" + +USE_REMOTE=false +SKIP_COPY=false + +function usage() { + echo "Usage: $0 --user [--remote] [--no-copy] [--ip ]" +} + +# Parse arguments +while (($# > 0)); do + case "$1" in + --user) + if (($# < 2)); then + echo "Missing --user argument" + usage + exit 1 + fi + MONITOR_USER="$2" + shift 2 + ;; + --remote) + USE_REMOTE=true + shift + ;; + --no-copy) + SKIP_COPY=true + shift + ;; + --ip) + if (($# < 2)); then + echo "Missing --ip argument" + usage + exit 1 + fi + MONITOR_HOST="$2" + shift 2 + ;; + *) + echo "Unknown argument: $1" + usage + exit 1 + ;; + esac +done + +if [[ -z "${MONITOR_USER}" ]]; then + echo "Missing --user argument" + usage + exit 1 +fi + +if [[ "${USE_REMOTE}" == true ]]; then + if ! scp "remote:${SDP_PATH}" "${SDP_PATH}"; then + echo "Failed to copy from remote. Continue? (y/n)" + read -r answer + case "$answer" in + [Yy]*) echo "Continuing with next steps..." ;; + *) + echo "Cancelled." + exit 1 + ;; + esac + fi +fi + +if [[ "${SKIP_COPY}" == false ]]; then + if ! scp "${SDP_PATH}" "${MONITOR_USER}@${MONITOR_HOST}:${SDP_PATH}"; then + echo "scp copy failed" + exit 1 + fi + echo "File copied to host: ${SDP_PATH}" +else + echo "Skipping copy; opening remote SDP directly" +fi + +ssh -f "${MONITOR_USER}@${MONITOR_HOST}" "DISPLAY=:0 ${MONITOR_PLAYER} '${SDP_PATH}' --network-caching=50" diff --git a/.script/sync-remote b/.script/sync-remote index 60a2b8161..0a261b254 100755 --- a/.script/sync-remote +++ b/.script/sync-remote @@ -8,7 +8,8 @@ import subprocess from colorama import Fore, Style -SRC_DIR = "/workspaces/RMCS/rmcs_ws/install" +RMCS_PATH = os.getenv("RMCS_PATH") or "/workspaces/RMCS" +SRC_DIR = os.path.join(RMCS_PATH, "rmcs_ws", "install") DST_DIR = "ssh://remote//rmcs_install" SOCKET_PATH = "/tmp/sync-remote" diff --git a/.script/template/env_setup.bash b/.script/template/env_setup.bash index aa904464e..8eed24169 100644 --- a/.script/template/env_setup.bash +++ b/.script/template/env_setup.bash @@ -1,13 +1,16 @@ #!/bin/bash -export ROS_LOCALHOST_ONLY=1 +: "${RMCS_PATH:=/workspaces/RMCS}" + +export ROS_AUTOMATIC_DISCOVERY_RANGE=LOCALHOST +export RCUTILS_COLORIZED_OUTPUT=1 source /opt/ros/jazzy/setup.bash if [ -f "/rmcs_install/local_setup.bash" ]; then source /rmcs_install/local_setup.bash -elif [ -f "/workspaces/RMCS/rmcs_ws/install/local_setup.bash" ]; then - source /workspaces/RMCS/rmcs_ws/install/local_setup.bash +elif [ -f "${RMCS_PATH}/rmcs_ws/install/local_setup.bash" ]; then + source "${RMCS_PATH}/rmcs_ws/install/local_setup.bash" fi export RMCS_ROBOT_TYPE="" diff --git a/.script/template/env_setup.zsh b/.script/template/env_setup.zsh index 518afb8f3..7501ebde0 100644 --- a/.script/template/env_setup.zsh +++ b/.script/template/env_setup.zsh @@ -1,16 +1,24 @@ -#!/bin/bash +#!/bin/zsh -export ROS_LOCALHOST_ONLY=1 +: "${RMCS_PATH:=/workspaces/RMCS}" + +export ROS_AUTOMATIC_DISCOVERY_RANGE=LOCALHOST +export RCUTILS_COLORIZED_OUTPUT=1 source /opt/ros/jazzy/setup.zsh if [ -f "/rmcs_install/local_setup.zsh" ]; then source /rmcs_install/local_setup.zsh -elif [ -f "/workspaces/RMCS/rmcs_ws/install/local_setup.zsh" ]; then - source /workspaces/RMCS/rmcs_ws/install/local_setup.zsh +elif [ -f "${RMCS_PATH}/rmcs_ws/install/local_setup.zsh" ]; then + source "${RMCS_PATH}/rmcs_ws/install/local_setup.zsh" fi eval "$(register-python-argcomplete ros2)" eval "$(register-python-argcomplete colcon)" export RMCS_ROBOT_TYPE="" +export PATH="${PATH}:${RMCS_PATH}/.script" + +fpath=("${RMCS_PATH}/.script/complete" $fpath) +autoload -Uz compinit +compinit diff --git a/Dockerfile b/Dockerfile index 37bf10973..ecce1882d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -18,6 +18,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ vim wget curl unzip \ zsh screen tmux \ usbutils net-tools iputils-ping \ + gstreamer1.0-tools gstreamer1.0-plugins-base gstreamer1.0-plugins-good \ ripgrep htop fzf \ libusb-1.0-0-dev \ libeigen3-dev \ @@ -81,19 +82,33 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ openssh-client \ lsb-release software-properties-common gnupg sudo \ python3-colorama python3-dpkt && \ - wget -O ./llvm-snapshot.gpg.key https://apt.llvm.org/llvm-snapshot.gpg.key && \ - apt-key add ./llvm-snapshot.gpg.key && \ - rm ./llvm-snapshot.gpg.key && \ - echo "deb https://apt.llvm.org/noble/ llvm-toolchain-noble main" > /etc/apt/sources.list.d/llvm-apt.list && \ - apt-get update && \ - version=`apt-cache search clangd- | grep clangd- | awk -F' ' '{print $1}' | sort -V | tail -1 | cut -d- -f2` && \ - apt-get install -y --no-install-recommends clangd-$version && \ update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-14 50 && \ update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-14 50 && \ - update-alternatives --install /usr/bin/clangd clangd /usr/bin/clangd-$version 50 && \ apt-get autoremove -y && apt-get clean && \ rm -rf /var/lib/apt/lists/* /tmp/* +# Install llvm-toolchain +ARG LLVM_VERSION=22 +RUN mkdir -p /etc/apt/keyrings && \ + wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key | gpg --dearmor -o /etc/apt/keyrings/apt.llvm.org.gpg && \ + chmod 644 /etc/apt/keyrings/apt.llvm.org.gpg && \ + echo "deb [signed-by=/etc/apt/keyrings/apt.llvm.org.gpg] https://apt.llvm.org/noble/ llvm-toolchain-noble-${LLVM_VERSION} main" \ + > /etc/apt/sources.list.d/llvm.list && \ + apt-get update && \ + apt-get install -y --no-install-recommends \ + clang-${LLVM_VERSION} clangd-${LLVM_VERSION} clang-format-${LLVM_VERSION} clang-tidy-${LLVM_VERSION} \ + lldb-${LLVM_VERSION} lld-${LLVM_VERSION} llvm-${LLVM_VERSION} && \ + update-alternatives --install /usr/bin/clang clang /usr/bin/clang-${LLVM_VERSION} 50 && \ + update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-${LLVM_VERSION} 50 && \ + update-alternatives --install /usr/bin/clangd clangd /usr/bin/clangd-${LLVM_VERSION} 50 && \ + update-alternatives --install /usr/bin/clang-format clang-format /usr/bin/clang-format-${LLVM_VERSION} 50 && \ + update-alternatives --install /usr/bin/clang-tidy clang-tidy /usr/bin/clang-tidy-${LLVM_VERSION} 50 && \ + update-alternatives --install /usr/bin/lldb lldb /usr/bin/lldb-${LLVM_VERSION} 50 && \ + update-alternatives --install /usr/bin/llvm-ar llvm-ar /usr/bin/llvm-ar-${LLVM_VERSION} 50 && \ + update-alternatives --install /usr/bin/llvm-ranlib llvm-ranlib /usr/bin/llvm-ranlib-${LLVM_VERSION} 50 && \ + update-alternatives --install /usr/bin/ld.lld ld.lld /usr/bin/ld.lld-${LLVM_VERSION} 50 && \ + apt-get autoremove -y && apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* + # Generate/load ssh key and setup unison RUN --mount=type=bind,target=/tmp/.ssh,source=.ssh,readonly=false \ cd /home/ubuntu && mkdir -p .ssh && \ @@ -109,6 +124,12 @@ RUN curl -LO https://github.com/neovim/neovim/releases/latest/download/nvim-linu rm -rf /opt/nvim && \ tar -C /opt -xzf nvim-linux-x86_64.tar.gz && \ rm nvim-linux-x86_64.tar.gz +ENV PATH="${PATH}:/opt/nvim-linux-x86_64/bin" + +# Install latest stable cmake for user ubuntu +RUN wget https://github.com/kitware/cmake/releases/download/v4.2.3/cmake-4.2.3-linux-x86_64.sh -O install.sh && \ + mkdir -p /opt/cmake/ && bash install.sh --skip-license --prefix=/opt/cmake/ --exclude-subdir && \ + rm install.sh # Change user RUN chsh -s /bin/zsh ubuntu && \ @@ -121,14 +142,15 @@ USER ubuntu # Install oh my zsh, change theme to af-magic and setup environment of zsh RUN sh -c "$(wget https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh -O -)" && \ sed -i 's/ZSH_THEME=\"[a-z0-9\-]*\"/ZSH_THEME="af-magic"/g' ~/.zshrc && \ - echo 'source ~/env_setup.zsh' >> ~/.zshrc && \ - echo 'export PATH="${PATH}:/opt/nvim-linux-x86_64/bin"' >> ~/.zshrc && \ - echo 'export PATH=${PATH}:/workspaces/RMCS/.script' >> ~/.zshrc + echo '# Hint: uncomment and set RMCS_PATH if RMCS is not located at /workspaces/RMCS.' >> ~/.zshrc && \ + echo '# export RMCS_PATH="/workspaces/RMCS"' >> ~/.zshrc && \ + echo 'source ~/env_setup.zsh' >> ~/.zshrc # Copy environment setup scripts COPY --chown=1000:1000 .script/template/env_setup.bash env_setup.bash COPY --chown=1000:1000 .script/template/env_setup.zsh env_setup.zsh + # Runtime container, will automatically launch the main program FROM rmcs-base AS rmcs-runtime diff --git a/README.md b/README.md index 1bb950ab6..dc365f69b 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ # RMCS RoboMaster Control System based on ROS2. +快速开始: [quick-start](https://github.com/Alliance-Algorithm/RMCS/wiki/Quick-Start) + ## Development ### Pre-requirements: diff --git a/docker-compose.yml b/docker-compose.yml index 384717e76..6d221280f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,20 +1,17 @@ services: rmcs-develop: image: qzhhhi/rmcs-develop:latest - container_name: rmcs-develop - user: "developer" - hostname: "developer" + user: "1000:1000" privileged: true volumes: - /dev:/dev:bind - /tmp/.X11-unix:/tmp/.X11-unix:bind - - /run/user/1000/wayland-0:/run/user/1000/wayland-0 - - ~/.config/nvim/:/home/developer/.config/nvim/:bind + - /run/user/1000/wayland-0:/run/user/1000/wayland-0:bind + - ${HOME}/.config/:${CONTAINER_HOME}/.config/:bind - .:/workspaces/RMCS:bind environment: - DISPLAY=${DISPLAY} - WAYLAND_DISPLAY=${WAYLAND_DISPLAY} network_mode: host tty: true - stdin_open: true - + stdin_open: true diff --git a/rmcs_ws/src/rmcs_executor/include/rmcs_executor/component.hpp b/rmcs_ws/src/rmcs_executor/include/rmcs_executor/component.hpp index cba9b55fa..bfb102888 100644 --- a/rmcs_ws/src/rmcs_executor/include/rmcs_executor/component.hpp +++ b/rmcs_ws/src/rmcs_executor/include/rmcs_executor/component.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -16,12 +17,12 @@ class Component { public: friend class Executor; - Component(const Component&) = delete; + Component(const Component&) = delete; Component& operator=(const Component&) = delete; - Component(Component&&) = delete; - Component& operator=(Component&&) = delete; + Component(Component&&) = delete; + Component& operator=(Component&&) = delete; - virtual ~Component(){}; + virtual ~Component() = default; virtual void before_pairing(const std::map& output_map) { (void)output_map; @@ -37,10 +38,10 @@ class Component { InputInterface() = default; - InputInterface(const InputInterface&) = delete; + InputInterface(const InputInterface&) = delete; InputInterface& operator=(const InputInterface&) = delete; - InputInterface(InputInterface&&) = delete; - InputInterface& operator=(InputInterface&&) = delete; + InputInterface(InputInterface&&) = delete; + InputInterface& operator=(InputInterface&&) = delete; ~InputInterface() { if (delete_data_when_deconstruct) { @@ -61,7 +62,7 @@ class Component { throw std::runtime_error("The interface has already been bound to somewhere"); data_pointer_ = new T(std::forward(args)...); - activated = true; + activated = true; delete_data_when_deconstruct = true; } @@ -71,7 +72,7 @@ class Component { throw std::runtime_error("The interface has already been bound to somewhere"); data_pointer_ = const_cast(&destination); - activated = true; + activated = true; } const T* operator->() const { return data_pointer_; } @@ -84,7 +85,7 @@ class Component { } T* data_pointer_ = nullptr; - bool activated = false; + bool activated = false; bool delete_data_when_deconstruct = false; }; @@ -96,10 +97,10 @@ class Component { OutputInterface() = default; - OutputInterface(const OutputInterface&) = delete; + OutputInterface(const OutputInterface&) = delete; OutputInterface& operator=(const OutputInterface&) = delete; - OutputInterface(OutputInterface&&) = delete; - OutputInterface& operator=(OutputInterface&&) = delete; + OutputInterface(OutputInterface&&) = delete; + OutputInterface& operator=(OutputInterface&&) = delete; ~OutputInterface() { if (active()) @@ -136,6 +137,7 @@ class Component { } template + requires std::constructible_from void register_output(const std::string& name, OutputInterface& interface, Args&&... args) { if (interface.active()) throw std::runtime_error("The interface has been activated"); @@ -144,6 +146,7 @@ class Component { } template + requires std::constructible_from std::shared_ptr create_partner_component(const std::string& name, Args&&... args) { initializing_component_name = name.c_str(); @@ -182,8 +185,8 @@ class Component { std::vector> partner_component_list_; - size_t dependency_count_ = 0; + std::size_t dependency_count_ = 0; std::unordered_set wanted_by_ = {}; }; -} // namespace rmcs_executor \ No newline at end of file +} // namespace rmcs_executor diff --git a/rmcs_ws/src/rmcs_executor/src/main.cpp b/rmcs_ws/src/rmcs_executor/src/main.cpp index 0de17487c..99311f24d 100644 --- a/rmcs_ws/src/rmcs_executor/src/main.cpp +++ b/rmcs_ws/src/rmcs_executor/src/main.cpp @@ -44,7 +44,7 @@ int main(int argc, char** argv) { std::vector component_descriptions; if (!executor->get_parameter("components", component_descriptions)) - throw std::runtime_error("para"); + throw std::runtime_error("Missing parameter 'components' or config is not found"); std::regex regex(R"(\s*(\S+)\s*->\s*(\S+)\s*)"); for (const auto& component_description : component_descriptions) {