From b3d75ca7b455f5d543bee0a7deacee5a1c68dedb Mon Sep 17 00:00:00 2001 From: Quintin Date: Sun, 17 Sep 2023 23:58:02 -0400 Subject: [PATCH 1/2] Install VSCode as part of Ansible dev role (#534) * VSCode apt * Fix path --- ansible/roles/dev/tasks/main.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/ansible/roles/dev/tasks/main.yml b/ansible/roles/dev/tasks/main.yml index 000313060..7bb562d6b 100644 --- a/ansible/roles/dev/tasks/main.yml +++ b/ansible/roles/dev/tasks/main.yml @@ -16,3 +16,23 @@ - name: Use ZSH as a default shell become: true command: chsh --shell /usr/bin/zsh {{ ansible_user_id }} + +- name: Add VSCode APT Key + become: true + apt_key: + url: https://packages.microsoft.com/keys/microsoft.asc + keyring: /usr/share/keyrings/packages.microsoft.gpg + +- name: Add VSCode APT List + become: true + apt_repository: + filename: vscode + repo: "deb [arch=amd64,arm64,armhf signed-by=/usr/share/keyrings/packages.microsoft.gpg] https://packages.microsoft.com/repos/code stable main" + +- name: Install VSCode APT Package + become: true + apt: + cache_valid_time: 604800 + state: latest + name: + - code From a9a5cd6cc820c40b922500501ad68a9292c37b09 Mon Sep 17 00:00:00 2001 From: Quintin Date: Mon, 18 Sep 2023 19:35:50 -0400 Subject: [PATCH 2/2] Ansible upgrades (#535) * VSCode apt * Fix path * Fix style.sh, add venv to gitignore, update dockerfile, comment ansible, make dev.yml perform sysstem upgrade, make ansible handle python virtualenv instead of bootstrap, specify versions exactly in pyproject, format some code in auton * Remove doing python venv work in bootstrap, now handled by ansible * Consolidate into one CI action, update gitignore, comment out moveit for now, fix dockerfile, add ci catkin profile, format package.xml, misc stuff * Run as root so github actions doesn't fail on github.com * Break into two --- .github/workflows/catkin.yml | 26 --- .github/workflows/ci.yml | 43 ++++ .github/workflows/style.yml | 19 -- .gitignore | 31 +-- CMakeLists.txt | 24 +- Dockerfile | 33 +-- ansible.sh | 4 +- .../roles/build/files/profiles/ci/config.yaml | 27 +++ .../build/files/profiles/debug/config.yaml | 28 +-- .../build/files/profiles/release/config.yaml | 28 +-- ansible/roles/build/tasks/main.yml | 26 +++ bootstrap.sh | 7 - package.xml | 216 ++++++++---------- pyproject.toml | 31 +-- src/esw/__init__.py | 0 src/esw/brushless.py | 3 - src/esw/cameras.py | 3 - src/esw/imu_driver.py | 1 - src/esw/science.py | 1 - src/navigation/gate.py | 1 - src/navigation/partial_gate.py | 1 - src/navigation/state.py | 10 +- src/navigation/waypoint.py | 15 +- src/teleop/jetson/arm_trajectory_server.py | 4 - style.sh | 59 +++-- 25 files changed, 324 insertions(+), 317 deletions(-) delete mode 100644 .github/workflows/catkin.yml create mode 100644 .github/workflows/ci.yml delete mode 100644 .github/workflows/style.yml create mode 100644 ansible/roles/build/files/profiles/ci/config.yaml create mode 100644 src/esw/__init__.py diff --git a/.github/workflows/catkin.yml b/.github/workflows/catkin.yml deleted file mode 100644 index e3e599cbf..000000000 --- a/.github/workflows/catkin.yml +++ /dev/null @@ -1,26 +0,0 @@ -name: CI -on: - pull_request: - branches: - - master -jobs: - build: - name: Build and Test - runs-on: ubuntu-latest - container: - image: umrover1/ros:latest - options: --user root - if: github.event.pull_request.draft == false - steps: - - uses: actions/checkout@v3 - with: - lfs: "true" - path: "src" - - name: Initialize catkin workspace - run: . /opt/ros/noetic/setup.sh && catkin init - - name: Build - run: . /opt/ros/noetic/setup.sh && catkin build -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_CLANG_TIDY=clang-tidy-12 - - name: Python requirements - run: pip3 install -r $GITHUB_WORKSPACE/src/requirements.txt - - name: Test - run: . /opt/ros/noetic/setup.sh && . $GITHUB_WORKSPACE/devel/setup.sh && catkin test -j1 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000..d8585ce5d --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,43 @@ +name: CI +on: + pull_request: + branches: + - master + push: + branches: + - master +jobs: + ci: + name: CI + runs-on: ubuntu-latest + container: + image: umrover1/ros:latest + options: --user root + steps: + - uses: actions/checkout@v4 + with: + lfs: "true" + # This makes sure that $GITHUB_WORKSPACE is the catkin workspace path + path: "src/mrover" + - name: Ensure Python Requirements + run: . /home/mrover/catkin_ws/src/mrover/venv/bin/activate && pip install -e "$GITHUB_WORKSPACE/src/mrover[dev]" + - name: Style Check + run: . /home/mrover/catkin_ws/src/mrover/venv/bin/activate && cd $GITHUB_WORKSPACE/src/mrover/ && ./style.sh + - name: Update ROS APT + if: github.event.pull_request.draft == false + run: runuser -u mrover -- rosdep update + - name: Ensure ROS APT Requirements + if: github.event.pull_request.draft == false + run: runuser -u mrover -- rosdep install --from-paths "$GITHUB_WORKSPACE/src" --ignore-src -r -y --rosdistro noetic + - name: Copy Catkin Profiles + if: github.event.pull_request.draft == false + run: rsync -r $GITHUB_WORKSPACE/src/mrover/ansible/roles/build/files/profiles $GITHUB_WORKSPACE/.catkin_tools + - name: Initialize + if: github.event.pull_request.draft == false + run: . /opt/ros/noetic/setup.sh && catkin init && catkin profile set ci + - name: Build + if: github.event.pull_request.draft == false + run: . /opt/ros/noetic/setup.sh && . /home/mrover/catkin_ws/src/mrover/venv/bin/activate && catkin build + - name: Test + if: github.event.pull_request.draft == false + run: . /opt/ros/noetic/setup.sh && . /home/mrover/catkin_ws/src/mrover/venv/bin/activate && . $GITHUB_WORKSPACE/devel/setup.sh && catkin test -j1 diff --git a/.github/workflows/style.yml b/.github/workflows/style.yml deleted file mode 100644 index 545203560..000000000 --- a/.github/workflows/style.yml +++ /dev/null @@ -1,19 +0,0 @@ -name: Style -on: - pull_request: - branches: - - master - push: - branches: - - master -jobs: - code-style: - name: Code Style Check - runs-on: ubuntu-latest - container: - image: umrover1/ros:latest - options: --user root - steps: - - uses: actions/checkout@v3 - - name: Style check C++/Python - run: $GITHUB_WORKSPACE/style.sh diff --git a/.gitignore b/.gitignore index 9c7675372..b33a46b98 100644 --- a/.gitignore +++ b/.gitignore @@ -3,33 +3,34 @@ __pycache__/ *.py[cod] *$py.class .mypy_cache/ +*.egg-info/ # Common IDE's, ideally this should be in global gitignore per user -**/.vscode/ -**/.idea/ -cmake-build*/ +.vscode/ +.idea/ +/cmake-build*/ #GUI Files +node_modules/ /src/teleop/gui/dist/ -/src/teleop/gui/node_modules/ /src/teleop/gui/src/static/map -**/keys.json* -**/yarn.lock* -**/yarn-error.log* +keys.json* +yarn.lock* +yarn-error.log* # Bag Files -bags/ - -# Bag Files -bags/ +/bags/ # Catkin -build/ -devel/ -logs/ +/build/ +/devel/ +/logs/ # Moteus moteus-cal* # CSV -*.csv \ No newline at end of file +*.csv + +# Virtual Environment +/venv/ diff --git a/CMakeLists.txt b/CMakeLists.txt index 03b28a876..5019ac533 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.16) -project(mrover VERSION 2024.0 LANGUAGES CXX) +project(mrover VERSION 2024.0.0 LANGUAGES CXX) ## Compile as C++17, supported in ROS Kinetic and newer, enable some static analysis set(CMAKE_CXX_STANDARD 17) @@ -199,26 +199,6 @@ else () rosbridge_server teleop_twist_joy gazebo_ros - moveit_commander - moveit_core - moveit_fake_controller_manager - moveit_kinematics - moveit_msgs - moveit_planners_chomp - moveit_planners_ompl - moveit_ros_benchmarks - moveit_ros_control_interface - moveit_ros_manipulation - moveit_ros_move_group - moveit_ros_occupancy_map_monitor - moveit_ros_perception - moveit_ros_planning - moveit_ros_planning_interface - moveit_ros_robot_interaction - moveit_ros_visualization - moveit_ros_warehouse - moveit_setup_assistant - moveit_simple_controller_manager ) # append subdirectories @@ -235,7 +215,7 @@ else () find_package(OpenCV REQUIRED COMPONENTS core aruco) find_package(gazebo REQUIRED) find_package(Eigen3 REQUIRED) - find_package(ZED 2) + find_package(ZED 2 QUIET) if (ZED_FOUND) set(CMAKE_CUDA_SEPARABLE_COMPILATION ON) set(CMAKE_CUDA_STANDARD 17) diff --git a/Dockerfile b/Dockerfile index 6d02b1f80..cd65b024e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,33 +1,34 @@ FROM ros:noetic -RUN apt-get update && apt-get upgrade -y -# Add apt repo for latest version of Git -RUN apt-get install software-properties-common -y && add-apt-repository ppa:git-core/ppa -y -RUN apt-get update && apt-get install -y \ - zsh neovim sudo git git-lfs \ - clang-format-12 clang-tidy-12 \ - python3-catkin-tools python3-pip -RUN DEBIAN_FRONTEND=noninteractive apt-get install keyboard-configuration -y +# DEBIAN_FRONTEND=noninteractive and keyboard-configuration are needed to prevent stdin prompting later on +# This was super annoying to figure out because otherwise the build would hang +# software-properties-common is needed for apt-add-repository +RUN apt-get update -y && apt-get upgrade -y && DEBIAN_FRONTEND=noninteractive apt-get install software-properties-common keyboard-configuration -y +RUN apt-add-repository ppa:ansible/ansible -y +RUN apt-add-repository ppa:git-core/ppa -y +RUN apt-get install -y ansible git git-lfs RUN useradd --create-home --groups sudo --shell /bin/zsh mrover # Give mrover user sudo access with no password RUN echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers USER mrover -RUN mkdir -p ~/catkin_ws/src/mrover +RUN mkdir -p /home/mrover/catkin_ws/src/mrover WORKDIR /home/mrover/catkin_ws/src/mrover -# ROS package manager (rosdep) reads this file to install dependencies +# Defines the APT packages that need to be installed +# rosdep is called from Ansible to install them ADD ./package.xml . -# Python package manager (pip) reads this file to install dependencies -ADD ./requirements.txt . -# Install ROS packages -RUN rosdep update && rosdep install --from-paths . --ignore-src -y --rosdistro=noetic +# Defines the Python packages that need to be installed +# pip is called from Ansible to install them +ADD ./pyproject.toml . +# Copy over all Ansible files +ADD ./ansible ./ansible +ADD ./ansible.sh . +RUN ./ansible.sh build.yml USER root # Remove apt cache to free up space in the image RUN apt-get clean && rm -rf /var/lib/apt/lists/* -# Install Python packags, sudo so it is a global install -RUN pip3 install -r ./requirements.txt USER mrover ENTRYPOINT [ "/bin/zsh" ] diff --git a/ansible.sh b/ansible.sh index 5cb4af68e..f37d0b3cc 100755 --- a/ansible.sh +++ b/ansible.sh @@ -9,6 +9,6 @@ fi sudo -v # Ensure Ansible has sudo permission -MROVER_PATH=$(dirname "$0") -CATKIN_WORKSPACE_PATH=$(realpath "${MROVER_PATH}"/../..) +readonly MROVER_PATH=$(dirname "$0") +readonly CATKIN_WORKSPACE_PATH=$(realpath "${MROVER_PATH}"/../..) ansible-playbook -i "localhost," -c local "${MROVER_PATH}"/ansible/"$1" --extra-vars "catkin_workspace=${CATKIN_WORKSPACE_PATH}" diff --git a/ansible/roles/build/files/profiles/ci/config.yaml b/ansible/roles/build/files/profiles/ci/config.yaml new file mode 100644 index 000000000..44661fe8f --- /dev/null +++ b/ansible/roles/build/files/profiles/ci/config.yaml @@ -0,0 +1,27 @@ +authors: [ ] +blacklist: [ ] +build_space: build +catkin_make_args: [ ] +cmake_args: + - -DCMAKE_BUILD_TYPE=Release + - -DCMAKE_CXX_FLAGS=-pipe + - -DCMAKE_C_COMPILER=clang-16 + - -DCMAKE_CXX_COMPILER=clang++-16 + - -DCMAKE_CXX_CLANG_TIDY=clang-tidy-16 +devel_layout: linked +devel_space: devel +extend_path: null +extends: null +install: false +install_space: install +isolate_install: false +jobs_args: [ ] +licenses: + - TODO +log_space: logs +maintainers: [ ] +make_args: [ ] +source_space: src +use_env_cache: false +use_internal_make_jobserver: true +whitelist: [ ] diff --git a/ansible/roles/build/files/profiles/debug/config.yaml b/ansible/roles/build/files/profiles/debug/config.yaml index 81a1c908f..004623cb6 100644 --- a/ansible/roles/build/files/profiles/debug/config.yaml +++ b/ansible/roles/build/files/profiles/debug/config.yaml @@ -1,14 +1,14 @@ -authors: [] -blacklist: [] +authors: [ ] +blacklist: [ ] build_space: build -catkin_make_args: [] +catkin_make_args: [ ] cmake_args: -- -DCMAKE_BUILD_TYPE=Debug -- -DCMAKE_CXX_FLAGS=-pipe -- -DCMAKE_C_COMPILER=clang-16 -- -DCMAKE_CXX_COMPILER=clang++-16 -- -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -- -DCMAKE_CUDA_COMPILER_LAUNCHER=ccache + - -DCMAKE_BUILD_TYPE=Debug + - -DCMAKE_CXX_FLAGS=-pipe + - -DCMAKE_C_COMPILER=clang-16 + - -DCMAKE_CXX_COMPILER=clang++-16 + - -DCMAKE_CXX_COMPILER_LAUNCHER=ccache + - -DCMAKE_CUDA_COMPILER_LAUNCHER=ccache devel_layout: linked devel_space: devel extend_path: null @@ -16,13 +16,13 @@ extends: null install: false install_space: install isolate_install: false -jobs_args: [] +jobs_args: [ ] licenses: -- TODO + - TODO log_space: logs -maintainers: [] -make_args: [] +maintainers: [ ] +make_args: [ ] source_space: src use_env_cache: false use_internal_make_jobserver: true -whitelist: [] +whitelist: [ ] diff --git a/ansible/roles/build/files/profiles/release/config.yaml b/ansible/roles/build/files/profiles/release/config.yaml index ed7c7bc69..8f6df2e90 100644 --- a/ansible/roles/build/files/profiles/release/config.yaml +++ b/ansible/roles/build/files/profiles/release/config.yaml @@ -1,14 +1,14 @@ -authors: [] -blacklist: [] +authors: [ ] +blacklist: [ ] build_space: build -catkin_make_args: [] +catkin_make_args: [ ] cmake_args: -- -DCMAKE_BUILD_TYPE=Release -- -DCMAKE_CXX_FLAGS=-march=native -pipe -- -DCMAKE_C_COMPILER=clang-16 -- -DCMAKE_CXX_COMPILER=clang++-16 -- -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -- -DCMAKE_CUDA_COMPILER_LAUNCHER=ccache + - -DCMAKE_BUILD_TYPE=Release + - -DCMAKE_CXX_FLAGS=-march=native -pipe + - -DCMAKE_C_COMPILER=clang-16 + - -DCMAKE_CXX_COMPILER=clang++-16 + - -DCMAKE_CXX_COMPILER_LAUNCHER=ccache + - -DCMAKE_CUDA_COMPILER_LAUNCHER=ccache devel_layout: linked devel_space: devel extend_path: null @@ -16,13 +16,13 @@ extends: null install: false install_space: install isolate_install: false -jobs_args: [] +jobs_args: [ ] licenses: -- TODO + - TODO log_space: logs -maintainers: [] -make_args: [] +maintainers: [ ] +make_args: [ ] source_space: src use_env_cache: false use_internal_make_jobserver: true -whitelist: [] +whitelist: [ ] diff --git a/ansible/roles/build/tasks/main.yml b/ansible/roles/build/tasks/main.yml index 2c7444fd7..223073a98 100644 --- a/ansible/roles/build/tasks/main.yml +++ b/ansible/roles/build/tasks/main.yml @@ -1,8 +1,10 @@ +# Allows us to install Python versions newer than 3.8 - name: Add Python PPA become: True apt_repository: repo: ppa:deadsnakes/ppa +# Allows us to install G++11, so we can use an updated libstdc++ which provides more standard library features (C++20) - name: Add GCC PPA become: True apt_repository: @@ -13,6 +15,7 @@ apt_key: url: https://apt.llvm.org/llvm-snapshot.gpg.key +# Allows us to install Clang 16 and other LLVM tools - name: Add LLVM APT List become: True apt_repository: @@ -25,6 +28,7 @@ url: https://apt.kitware.com/keys/kitware-archive-latest.asc keyring: /usr/share/keyrings/kitware-archive-keyring.gpg +# Allows us to install CMake versions newer than 3.16 - name: Add CMake APT List become: True apt_repository: @@ -42,6 +46,13 @@ repo: deb http://packages.ros.org/ros/ubuntu {{ ubuntu_release }} main filename: ros +- name: Upgrade APT Packages + become: True + apt: + cache_valid_time: 604800 + state: latest + upgrade: yes + - name: Install APT Packages become: True apt: @@ -53,23 +64,29 @@ - neovim - sudo - cmake + # Caches intermediate build files, speeds up compilation over time - ccache + # Faster than make - ninja-build - tmux - zstd - htop - curl + - unzip + - rsync - python3-pip - python3-rosdep - python3-catkin-tools - python3-virtualenvwrapper - clang-16 - clangd-16 + - clang-tidy-16 - clang-format-16 - lld-16 - lldb-16 - g++-11 - python3.10 + - python3.10-dev - python3.10-venv - ros-{{ ros_distro }}-rosbash @@ -77,6 +94,7 @@ become: True command: rosdep init args: + # This command will be skipped if this file already exists creates: /etc/ros/rosdep/sources.list.d/20-default.list - name: Update rosdep @@ -133,3 +151,11 @@ path: /usr/bin/clang-16 link: /usr/bin/clang priority: 160 + +- name: Setup Python Virtual Environment + pip: + name: + # Installs from pyproject.toml + - "{{ catkin_workspace }}/src/mrover[dev]" + virtualenv: "{{ catkin_workspace }}/src/mrover/venv" + virtualenv_command: python3.10 -m venv diff --git a/bootstrap.sh b/bootstrap.sh index b3b922651..ce0b241fe 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -60,13 +60,6 @@ fi echo -e "${GREY_BOLD}Using Ansible to finish up ...${NC}" ${MROVER_PATH}/ansible.sh dev.yml -if [ ! -d ${MROVER_PATH}/venv ]; then - echo -e "${GREY_BOLD}Setting up Python virtual environment ...${NC}" - python3.10 -m venv ${MROVER_PATH}/venv - source ${MROVER_PATH}/venv/bin/activate - pip install -e "${MROVER_PATH}[dev]" -fi - if [ "${FIRST_TIME_SETUP}" ]; then echo -e "${GREY_BOLD}All done! Welcome to MRover!${NC}" echo -e "${YELLOW_BOLD}Please log out and back in!${NC}" diff --git a/package.xml b/package.xml index c7dba2fad..e87ee3c2c 100644 --- a/package.xml +++ b/package.xml @@ -1,119 +1,103 @@ - mrover - 1.0.0 - The MRover Package - - MRover - - - - - MIT - - - - - - - - - - - - - - - - - - - - - - - message_generation - - - - - - message_runtime - - - - - - - catkin - roscpp - rospy - std_msgs - nodelet - roscpp - rospy - std_msgs - roscpp - rospy - std_msgs - nodelet - xacro - joint_state_publisher - robot_state_publisher - ros_numpy - rosbridge_server - tf2_web_republisher - - - rviz - hector_trajectory_server - - - compressed_depth_image_transport - compressed_image_transport - theora_image_transport - tf2_geometry_msgs - tf2_ros - tf2 - image_transport - sensor_msgs - dynamic_reconfigure - python3-cairosvg - python3-joblib - rtabmap_ros - - - rviz_imu_plugin - robot_localization - nmea_navsat_driver - - - smach_ros - - - teleop_twist_joy - - - gazebo_ros - hector_gazebo - teleop_twist_keyboard - - - moveit - - - mavlink - mavros - mavros_extras - mavros_msgs - - - rosunit - rostest - - - - - - + mrover + 2024.0.0 + The MRover Package + + MRover + + + + + GPLv3 + + https://github.com/umrover/mrover-ros + + + + + + + + + + + + + + + + + message_generation + + + + + + message_runtime + + + + + + + catkin + roscpp + rospy + std_msgs + nodelet + roscpp + rospy + std_msgs + roscpp + rospy + std_msgs + nodelet + xacro + joint_state_publisher + robot_state_publisher + rosbridge_server + tf2_web_republisher + + + rviz + hector_trajectory_server + + + tf2 + tf2_ros + tf2_geometry_msgs + image_transport + theora_image_transport + compressed_image_transport + compressed_depth_image_transport + sensor_msgs + dynamic_reconfigure + + + rviz_imu_plugin + robot_localization + nmea_navsat_driver + + + smach_ros + control_msgs + + + teleop_twist_joy + + + gazebo_ros + hector_gazebo + teleop_twist_keyboard + + + rosunit + rostest + + + + + + diff --git a/pyproject.toml b/pyproject.toml index 138b596b7..17c26b5cc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "mrover" -version = "2024.0" +version = "2024.0.0" description = "MRover Python Code" readme = "README.md" requires-python = ">=3.10.0" @@ -9,23 +9,26 @@ maintainers = [ { name = "Michigan Mars Rover Team" } ] dependencies = [ - "django", - "empy", - "numpy", - "pandas", - "shapely", - "pyserial", - "moteus", - "pymap3d", - "aenum", - "pyyaml", - "rospkg", + # ROS dependencies + "rospkg==1.5.0", + "netifaces==0.11.0", + "defusedxml==0.7.1", + # MRover dependencies + "Django==4.2.5", + "empy==3.3.4", + "numpy==1.26.0", + "pandas==2.1.0", + "shapely==2.0.1", + "pyserial==3.5", + "moteus==0.3.59", + "pymap3d==3.0.1", + "aenum==3.1.15", ] [project.optional-dependencies] dev = [ - "black", - "mypy", + "black==23.9.1", + "mypy==1.5.1", ] [project.urls] diff --git a/src/esw/__init__.py b/src/esw/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/src/esw/brushless.py b/src/esw/brushless.py index 59b9b73ff..0cd9f40bc 100755 --- a/src/esw/brushless.py +++ b/src/esw/brushless.py @@ -125,12 +125,10 @@ def is_mode_indicating_error(mode: int) -> bool: class MoteusBridge: - MOTEUS_RESPONSE_TIME_INDICATING_DISCONNECTED_S = 0.01 ROVER_NODE_TO_MOTEUS_WATCHDOG_TIMEOUT_S = 0.1 def __init__(self, can_id: int, transport, gear_ratio: int): - self._can_id = can_id self.controller = moteus.Controller(id=can_id, transport=transport) self.command_lock = threading.Lock() @@ -369,7 +367,6 @@ async def send_command(self) -> None: for bridge in self._motor_bridges.values(): if lost_communication_now: - # If we only just lost communications this iteration. if not self._lost_communication: rospy.loginfo( diff --git a/src/esw/cameras.py b/src/esw/cameras.py index 3d7c20438..9ff860c5a 100755 --- a/src/esw/cameras.py +++ b/src/esw/cameras.py @@ -169,7 +169,6 @@ def __del__(self) -> None: class StreamManager: - MAX_STREAMS: int = rospy.get_param("cameras/max_streams") """ The maximum number of streams that can be simultaneously sustained. @@ -316,7 +315,6 @@ def handle_req(self, req: ChangeCamerasRequest) -> ChangeCamerasResponse: # If a stream is being requested... # (resolution == -1 means a request to cancel stream) if req.camera_cmd.resolution >= 0: - # If we cannot handle any more streams, return False. available_port_arr = [True, True, True, True] for i, stream in enumerate(self._stream_by_device): @@ -414,7 +412,6 @@ def send( # Transmit loop while True: - ret, frame = cap_send.read() if not ret: rospy.logerr("Empty frame") diff --git a/src/esw/imu_driver.py b/src/esw/imu_driver.py index 798f8c92a..22ea8b084 100755 --- a/src/esw/imu_driver.py +++ b/src/esw/imu_driver.py @@ -91,7 +91,6 @@ def main(): attempts = 0 while not rospy.is_shutdown(): - # try to read a line from the serial connection, # if this fails 100 times in a row then end the program try: diff --git a/src/esw/science.py b/src/esw/science.py index 71ed6cdbe..a77cdf69b 100755 --- a/src/esw/science.py +++ b/src/esw/science.py @@ -90,7 +90,6 @@ class ScienceBridge: _last_mcu_active: Bool def __init__(self) -> None: - self._active_publisher = rospy.Publisher("science_mcu_active", Bool, queue_size=1) self._mcu_active_timeout_s = rospy.get_param("science/info/mcu_active_timeout_s") diff --git a/src/navigation/gate.py b/src/navigation/gate.py index 3635b7faa..3638e8004 100644 --- a/src/navigation/gate.py +++ b/src/navigation/gate.py @@ -216,7 +216,6 @@ class GateTraverseStateTransitions(Enum): class GateTraverseState(BaseState): - STOP_THRESH = get_rosparam("gate/stop_thresh", 0.2) DRIVE_FWD_THRESH = get_rosparam("gate/drive_fwd_thresh", 0.34) # 20 degrees APPROACH_DISTANCE = get_rosparam("gate/approach_distance", 2.0) diff --git a/src/navigation/partial_gate.py b/src/navigation/partial_gate.py index e76f2e44d..88e1df022 100644 --- a/src/navigation/partial_gate.py +++ b/src/navigation/partial_gate.py @@ -64,7 +64,6 @@ class PartialGateStateTransitions(Enum): class PartialGateState(BaseState): - traj: Optional[PartialGateTrajectory] = None def __init__( diff --git a/src/navigation/state.py b/src/navigation/state.py index 23c1e8926..c35295f33 100644 --- a/src/navigation/state.py +++ b/src/navigation/state.py @@ -1,5 +1,5 @@ from abc import ABC -from typing import List +from typing import List, Optional import smach from context import Context @@ -19,9 +19,9 @@ def __init__( self, context: Context, own_transitions: List[str], - add_outcomes: List[str] = None, - add_input_keys: List[str] = None, - add_output_keys: List[str] = None, + add_outcomes: Optional[List[str]] = None, + add_input_keys: Optional[List[str]] = None, + add_output_keys: Optional[List[str]] = None, ): add_outcomes = add_outcomes or [] add_input_keys = add_input_keys or [] @@ -72,7 +72,7 @@ def reset(self): def evaluate(self, ud: smach.UserData) -> str: """Override me instead of execute!""" - pass + raise NotImplementedError class DoneStateTransitions(Enum): diff --git a/src/navigation/waypoint.py b/src/navigation/waypoint.py index d86cc8029..98e6a5aac 100644 --- a/src/navigation/waypoint.py +++ b/src/navigation/waypoint.py @@ -1,11 +1,10 @@ -from typing import List - -import numpy as np -import rospy +from typing import List, Optional import tf2_ros -from context import Context, Environment + +import numpy as np from aenum import Enum, NoAlias +from context import Context from state import BaseState from util.ros_utils import get_rosparam @@ -31,9 +30,9 @@ class WaypointState(BaseState): def __init__( self, context: Context, - add_outcomes: List[str] = None, - add_input_keys: List[str] = None, - add_output_keys: List[str] = None, + add_outcomes: Optional[List[str]] = None, + add_input_keys: Optional[List[str]] = None, + add_output_keys: Optional[List[str]] = None, ): add_outcomes = add_outcomes or [] add_input_keys = add_input_keys or [] diff --git a/src/teleop/jetson/arm_trajectory_server.py b/src/teleop/jetson/arm_trajectory_server.py index d91dcdce2..94a213ad8 100755 --- a/src/teleop/jetson/arm_trajectory_server.py +++ b/src/teleop/jetson/arm_trajectory_server.py @@ -74,17 +74,14 @@ def error_threshold_exceeded(feedback: FollowJointTrajectoryFeedback) -> str: class MoveItAction(object): - # Rearranges the point path following the name convention joint_0, ... joint_6 def rearrange(self, joint_trajectory: JointTrajectory) -> None: - mapping = [joint_trajectory.joint_names.index(j) for j in conf_joint_names] # Return early if already arranged properly if mapping == sorted(mapping): return for point in joint_trajectory.points: - temp_positions: List[float] = [] temp_velocities: List[float] = [] temp_accelerations: List[float] = [] @@ -121,7 +118,6 @@ def __init__(self, name: str) -> None: # Action callback def execute_cb(self, goal: FollowJointTrajectoryGoal) -> None: - rospy.loginfo("Executing FollowJointTrajectory Action") # It is required to rearrange the arrays because MoveIt doesn't guarantee order preservation self.rearrange(goal.trajectory) diff --git a/style.sh b/style.sh index 0ca03c21b..39ff40b7c 100755 --- a/style.sh +++ b/style.sh @@ -3,58 +3,67 @@ # See: https://vaneyckt.io/posts/safer_bash_scripts_with_set_euxo_pipefail/ set -Eeuo pipefail -RED='\033[0;31m' -NC='\033[0m' +readonly RED='\033[0;31m' +readonly NC='\033[0m' + +print_update_error() { + echo -e "${RED}[Error] Please update with ./ansible.sh build.yml${NC}" + exit 1 +} ## Check that all tools are installed -clang_format_executable=clang-format-16 -clang_format_executable_path=$(which "$clang_format_executable") +readonly clang_format_executable=clang-format-16 +readonly clang_format_executable_path=$(which "$clang_format_executable") if [ ! -x "$clang_format_executable_path" ]; then - echo -e "${RED}[Error] Please install clang-format with: sudo apt install ${clang_format_executable}${NC}" - exit 1 + echo -e "${RED}[Error] Could not find clang-format-16${NC}" + print_update_error fi -black_executable=black -black_executable_path=$(which "$black_executable") +readonly black_executable=black +readonly black_executable_path=$(which "$black_executable") if [ ! -x "$black_executable_path" ]; then - echo -e "${RED}[Error] Please run pip3 install -r requirements.txt${NC}" - exit 1 + echo -e "${RED}[Error] Could not find black${NC}" + print_update_error fi # Style check Python with black -if ! black --version | grep -q 'black, 22.8.0'; then +if ! black --version | grep -q 'black, 23.9.1'; then echo -e "${RED}[Error] Wrong black version${NC}" - exit 1 + print_update_error fi -mypy_executable=mypy -mypy_executable_path=$(which "$mypy_executable") +readonly mypy_executable=mypy +readonly mypy_executable_path=$(which "$mypy_executable") if [ ! -x "$mypy_executable_path" ]; then - echo -e "${RED}[Error] Please run pip3 install -r requirements.txt${NC}" - exit 1 + echo -e "${RED}[Error] Could not find mypy${NC}" + print_update_error fi -if ! mypy --version | grep -q 'mypy 0.971'; then +if ! mypy --version | grep -q 'mypy 1.5.1'; then echo -e "${RED}[Error] Wrong mypy version${NC}" - exit 1 + print_update_error fi ## Run checks -# Fail immediately if any command below fails -set -Eeo pipefail - echo "Style checking C++ ..." -find ./src -regex '.*\.\(cpp\|hpp\|h\)' -exec "$clang_format_executable_path" --dry-run -style=file -i {} \; +readonly FOLDERS=( + ./src/perception + ./src/gazebo + ./src/util +) +for FOLDER in "${FOLDERS[@]}"; do + find "${FOLDER}" -regex '.*\.\(cpp\|hpp\|h\)' -exec "$clang_format_executable_path" --dry-run -style=file -i {} \; +done echo "Done" +echo echo "Style checking Python with black ..." -"$black_executable_path" --check --diff --line-length=120 ./src ./scripts -echo "Done" +"$black_executable_path" --line-length=120 ./src ./scripts +echo echo "Style checking Python with mypy ..." "$mypy_executable_path" --config-file mypy.ini --check ./src ./scripts -echo "Done"