From d0e343acc1cd685236dbae22f5d3b9eb9d9da526 Mon Sep 17 00:00:00 2001 From: qhdwight Date: Sun, 17 Sep 2023 23:39:20 -0400 Subject: [PATCH 1/7] VSCode apt --- 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..66f27869a 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: /etc/apt/keyrings/packages.microsoft.gpg + +- name: Add VSCode APT List + become: true + apt_repository: + filename: vscode + repo: "deb [arch=amd64,arm64,armhf signed-by=/etc/apt/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 6f59ce0672103be531e288797a6a3055bce95878 Mon Sep 17 00:00:00 2001 From: qhdwight Date: Sun, 17 Sep 2023 23:43:01 -0400 Subject: [PATCH 2/7] Fix path --- ansible/roles/dev/tasks/main.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ansible/roles/dev/tasks/main.yml b/ansible/roles/dev/tasks/main.yml index 66f27869a..7bb562d6b 100644 --- a/ansible/roles/dev/tasks/main.yml +++ b/ansible/roles/dev/tasks/main.yml @@ -21,13 +21,13 @@ become: true apt_key: url: https://packages.microsoft.com/keys/microsoft.asc - keyring: /etc/apt/keyrings/packages.microsoft.gpg + 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=/etc/apt/keyrings/packages.microsoft.gpg] https://packages.microsoft.com/repos/code stable main" + 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 From 75749da72412a822064daffdb13331c7d9f35a38 Mon Sep 17 00:00:00 2001 From: qhdwight Date: Mon, 18 Sep 2023 12:34:40 -0400 Subject: [PATCH 3/7] 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 --- .gitignore | 5 +- Dockerfile | 25 ++++----- ansible/roles/build/tasks/main.yml | 24 +++++++++ pyproject.toml | 26 +++++----- 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 +++++++++++++--------- 15 files changed, 96 insertions(+), 82 deletions(-) create mode 100644 src/esw/__init__.py diff --git a/.gitignore b/.gitignore index 9c7675372..2ac606dbf 100644 --- a/.gitignore +++ b/.gitignore @@ -32,4 +32,7 @@ logs/ moteus-cal* # CSV -*.csv \ No newline at end of file +*.csv + +# Virtual Environment +venv/ \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 6d02b1f80..454b42b28 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,33 +1,26 @@ 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 +RUN apt-get update -y && apt-get upgrade -y && apt-get install software-properties-common -y +RUN apt-add-repository ppa:ansible/ansible -y +RUN apt-add-repository ppa:git-core/ppa -y +RUN apt 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 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 +ADD ./pyproject.toml . +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/roles/build/tasks/main.yml b/ansible/roles/build/tasks/main.yml index 2c7444fd7..2565fc41e 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,12 +64,16 @@ - 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 @@ -77,6 +92,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 +149,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/pyproject.toml b/pyproject.toml index 138b596b7..abc2757c3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,23 +9,23 @@ maintainers = [ { name = "Michigan Mars Rover Team" } ] dependencies = [ - "django", - "empy", - "numpy", - "pandas", - "shapely", - "pyserial", - "moteus", - "pymap3d", - "aenum", - "pyyaml", - "rospkg", + "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", + "PyYAML==6.0.1", + "rospkg==1.5.0", ] [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..2afe1daf3 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" From e2a4fdcdbc8d2e866daa4b404a7c49d531105d5b Mon Sep 17 00:00:00 2001 From: qhdwight Date: Mon, 18 Sep 2023 12:35:15 -0400 Subject: [PATCH 4/7] Remove doing python venv work in bootstrap, now handled by ansible --- bootstrap.sh | 7 ------- 1 file changed, 7 deletions(-) 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}" From 5dfb43eb89455226a64e5919729c68841f9bb5f8 Mon Sep 17 00:00:00 2001 From: qhdwight Date: Mon, 18 Sep 2023 18:26:20 -0400 Subject: [PATCH 5/7] Consolidate into one CI action, update gitignore, comment out moveit for now, fix dockerfile, add ci catkin profile, format package.xml, misc stuff --- .github/workflows/catkin.yml | 26 --- .github/workflows/ci.yml | 39 ++++ .github/workflows/style.yml | 19 -- .gitignore | 28 ++- CMakeLists.txt | 24 +- Dockerfile | 12 +- 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 | 2 + package.xml | 216 ++++++++---------- pyproject.toml | 9 +- style.sh | 4 +- 14 files changed, 231 insertions(+), 235 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 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..445697edb --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,39 @@ +name: CI +on: + pull_request: + branches: + - master + push: + branches: + - master +jobs: + ci: + name: CI + runs-on: ubuntu-latest + container: + image: umrover1/ros:latest + 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: Ensure APT Requirements + if: github.event.pull_request.draft == false + run: rosdep update && 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 2ac606dbf..b33a46b98 100644 --- a/.gitignore +++ b/.gitignore @@ -3,30 +3,28 @@ __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* @@ -35,4 +33,4 @@ moteus-cal* *.csv # Virtual Environment -venv/ \ No newline at end of file +/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 454b42b28..cd65b024e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,9 +1,12 @@ FROM ros:noetic -RUN apt-get update -y && apt-get upgrade -y && apt-get install software-properties-common -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 install -y ansible git git-lfs +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 @@ -12,8 +15,13 @@ RUN echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers USER mrover RUN mkdir -p /home/mrover/catkin_ws/src/mrover WORKDIR /home/mrover/catkin_ws/src/mrover +# Defines the APT packages that need to be installed +# rosdep is called from Ansible to install them ADD ./package.xml . +# 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 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 2565fc41e..223073a98 100644 --- a/ansible/roles/build/tasks/main.yml +++ b/ansible/roles/build/tasks/main.yml @@ -80,11 +80,13 @@ - 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 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 abc2757c3..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,6 +9,11 @@ maintainers = [ { name = "Michigan Mars Rover Team" } ] dependencies = [ + # 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", @@ -18,8 +23,6 @@ dependencies = [ "moteus==0.3.59", "pymap3d==3.0.1", "aenum==3.1.15", - "PyYAML==6.0.1", - "rospkg==1.5.0", ] [project.optional-dependencies] diff --git a/style.sh b/style.sh index 2afe1daf3..39ff40b7c 100755 --- a/style.sh +++ b/style.sh @@ -55,8 +55,8 @@ readonly FOLDERS=( ./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 {} \; +for FOLDER in "${FOLDERS[@]}"; do + find "${FOLDER}" -regex '.*\.\(cpp\|hpp\|h\)' -exec "$clang_format_executable_path" --dry-run -style=file -i {} \; done echo "Done" From 20772123308cc43d451f0742b92d5deba888ebcf Mon Sep 17 00:00:00 2001 From: qhdwight Date: Mon, 18 Sep 2023 19:21:27 -0400 Subject: [PATCH 6/7] Run as root so github actions doesn't fail on github.com --- .github/workflows/ci.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 445697edb..5d8da8f73 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,6 +12,7 @@ jobs: runs-on: ubuntu-latest container: image: umrover1/ros:latest + options: --user root steps: - uses: actions/checkout@v4 with: @@ -22,9 +23,9 @@ jobs: 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: Ensure APT Requirements + - name: Ensure ROS APT Requirements if: github.event.pull_request.draft == false - run: rosdep update && rosdep install --from-paths "$GITHUB_WORKSPACE/src" --ignore-src -r -y --rosdistro noetic + run: runuser -u mrover -- rosdep update && 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 From 68e1783f48a70f11fe1b1a80a5f8b049b5669dac Mon Sep 17 00:00:00 2001 From: qhdwight Date: Mon, 18 Sep 2023 19:27:39 -0400 Subject: [PATCH 7/7] Break into two --- .github/workflows/ci.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5d8da8f73..d8585ce5d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,9 +23,12 @@ jobs: 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 update && rosdep install --from-paths "$GITHUB_WORKSPACE/src" --ignore-src -r -y --rosdistro noetic + 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