diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 3e0758ddcb..39cf451786 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -11,9 +11,13 @@ concurrency: cancel-in-progress: true jobs: - ubuntu22-tests: - name: Ubuntu 22.04 Build - runs-on: ubuntu-22.04 + multiplatform-build: + strategy: + matrix: + platform: [ ubuntu-22.04, ubuntu-24.04 ] + + name: Ubuntu Alternate Builds + runs-on: ${{ matrix.platform }} steps: # checks-out the repository under $GITHUB_WORKSPACE - uses: actions/checkout@v2 @@ -25,22 +29,24 @@ jobs: - name: Software Build Test run: | cd src - bazel build --show_timestamps \ - -- //... -//software:unix_full_system \ - -//software/simulated_tests/... \ - -//software/ai/hl/... \ - -//software/field_tests/... \ - -//software/embedded/... \ + bazel build --show_timestamps --copt=-O3 \ + -- //... -//software:unix_full_system \ + -//software/simulated_tests/... \ + -//software/ai/hl/... \ + -//software/field_tests/... \ + -//software/embedded/... \ + -//cc_toolchain/... - name: Jetson Nano Build Test run: | cd src - bazel build --cpu=jetson_nano //software/embedded:thunderloop_main --copt=-O3 --//software/embedded:host_platform=NANO + bazel build //software/embedded:thunderloop_main --copt=-O3 --//software/embedded:host_platform=NANO --platforms=//cc_toolchain:robot - name: Raspberry Pi Build Test run: | cd src - bazel build --cpu=jetson_nano //software/embedded:thunderloop_main --copt=-O3 --//software/embedded:host_platform=PI + bazel build //software/embedded:thunderloop_main --copt=-O3 --//software/embedded:host_platform=PI --platforms=//cc_toolchain:robot + software-tests: name: Software Tests @@ -61,7 +67,8 @@ jobs: -//software/simulated_tests/... \ -//software/ai/hl/... \ -//software/field_tests/... \ - -//software/ai/navigator/... + -//software/ai/navigator/... \ + -//cc_toolchain/... robot-tests: name: Robot Software Tests @@ -90,12 +97,14 @@ jobs: - name: Jetson Nano Build run: | cd src - bazel build --cpu=jetson_nano //software/embedded:thunderloop_main --copt=-O3 --//software/embedded:host_platform=NANO + bazel build //software/embedded:thunderloop_main --copt=-O3 --//software/embedded:host_platform=NANO --platforms=//cc_toolchain:robot + - name: Raspberry Pi Build run: | cd src - bazel build --cpu=jetson_nano //software/embedded:thunderloop_main --copt=-O3 --//software/embedded:host_platform=PI + bazel build //software/embedded:thunderloop_main --copt=-O3 --//software/embedded:host_platform=PI --platforms=//cc_toolchain:robot + simulated-gameplay-tests: name: Simulated Gameplay Tests @@ -112,9 +121,9 @@ jobs: run: | cd src bazel test --copt=-O3 --flaky_test_attempts=3 --show_timestamps \ - //software:unix_full_system \ - //software/simulated_tests/... \ - //software/ai/hl/... \ + //software:unix_full_system \ + //software/simulated_tests/... \ + //software/ai/hl/... \ //software/ai/navigator/... - name: Upload simulated test proto logs diff --git a/docs/getting-started-wsl.md b/docs/getting-started-wsl.md index 999f86e7b8..1e48c769b8 100644 --- a/docs/getting-started-wsl.md +++ b/docs/getting-started-wsl.md @@ -39,7 +39,7 @@ If you are not using Windows 11 and would prefer not to upgrade, you can follow 3. Now, let's install Ubuntu. - Download the WSL2 kernel from [here](https://docs.microsoft.com/en-us/windows/wsl/wsl2-kernel). - Open a PowerShell window and run command `wsl --set-default-version 2` to use WSL2 by default. - - Install Ubuntu 20.04 LTS or Ubuntu 22.04 LTS from the Microsoft Store. + - Install Ubuntu 20.04 LTS, Ubuntu 22.04 LTS or Ubuntu 24.04 LTS from the Microsoft Store. - Open the Ubuntu app in the Start menu. It will open a command prompt and ask you to create a new UNIX username and password for your WSL2 Ubuntu installation. ### X Server Setup diff --git a/docs/getting-started.md b/docs/getting-started.md index 59dd069ed1..4c6d3bbd54 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -66,9 +66,15 @@ These instructions assume you have a basic understanding of Linux and the comman ### Operating systems -We currently only support Linux, specifically Ubuntu 20.04 LTS and Ubuntu 22.04 LTS. You are welcome to use a different version or distribution of Linux, but may need to make some tweaks in order for things to work. +We currently only support Linux, specifically Ubuntu. -You can use Ubuntu 20.04 LTS and Ubuntu 22.04 LTS inside Windows through Windows Subsystem for Linux, by following [this guide](./getting-started-wsl.md). **Running and developing Thunderbots on Windows is experimental and not officially supported.** +If you have a X86_64 machine, we support Ubuntu 20.04 LTS, Ubuntu 22.04 LTS and Ubuntu 24.04 LTS. + +If you have a ARM64 (also known as AARCH64) machine, we support Ubuntu 24.04 LTS. + +You are welcome to use a different version or distribution of Linux, but may need to make some tweaks in order for things to work. + +You can use Ubuntu 20.04 LTS, Ubuntu 22.04 LTS or Ubuntu 24.04 LTS inside Windows through Windows Subsystem for Linux, by following [this guide](./getting-started-wsl.md). **Running and developing Thunderbots on Windows is experimental and not officially supported.** ### Getting the Code @@ -344,7 +350,7 @@ Tracy also samples call stacks. If the profiled binary is run with root permissi ## Building for the robot -To build for the robot computer, build the target with the `--cpu=jetson_nano` flag and the toolchain will automatically build using the ARM toolchain. For example, `bazel build --cpu=jetson_nano //software/geom/...`. +To build for the robot computer, build the target with the `--platforms=//cc_toolchain:robot` flag and the toolchain will automatically build using the ARM toolchain. For example, `bazel build --platforms=//cc_toolchain:robot //software/geom/...`. ## Deploying Robot Software to the robot @@ -352,7 +358,7 @@ We use Ansible to automatically update software running on the robot. [More info To update binaries on a working robot, you can run: -`bazel run //software/embedded/ansible:run_ansible --cpu=jetson_nano --//software/embedded:host_platform= -- --playbook deploy_robot_software.yml --hosts --ssh_pass ` +`bazel run //software/embedded/ansible:run_ansible --platforms=//cc_toolchain:robot --//software/embedded:host_platform= -- --playbook deploy_robot_software.yml --hosts --ssh_pass ` Where `` is the robot platform you are deploying to (`PI` or `NANO`), and `` is the IP address of the robot you are deploying to. The `robot_password` is the password used to login to the `robot` user on the robot. diff --git a/docs/robot-software-architecture.md b/docs/robot-software-architecture.md index f806e76e1c..9f6059524b 100644 --- a/docs/robot-software-architecture.md +++ b/docs/robot-software-architecture.md @@ -20,7 +20,10 @@ For a more detailed look at how Ansible works, [see the RFC](https://docs.google.com/document/d/1hN3Us2Vjr8z6ihqUVp_3L7rrjKc-EZ-l2hZJc31gNOc/edit) -Example command: `bazel run //software/embedded/ansible:run_ansible --cpu=jetson_nano --//software/embedded:host_platform= -- --playbook deploy_robot_software.yml --hosts --ssh_pass ` +Example command: `bazel run //software/embedded/ansible:run_ansible --platforms=//cc_toolchain:robot --//software/embedded:host_platform= -- --playbook deploy_robot_software.yml --hosts --ssh_pass ` +* : `PI` or `NANO` depending on the computer on the robot +* : IP address of the robot +* : Password of the robot More commands available [here](useful-robot-commands.md#off-robot-commands) diff --git a/docs/useful-robot-commands.md b/docs/useful-robot-commands.md index 5dd76fdc69..431f7c3c45 100644 --- a/docs/useful-robot-commands.md +++ b/docs/useful-robot-commands.md @@ -86,8 +86,8 @@ The IP address of the robots on the tbots network is `192.168.0.20` so Individual miscellaneous tasks (ex reboot, shutdown, rtt test) can be run through the `misc.yml` playbook by specifying the corresponding tag. -To view a list of supported arguments, run -`bazel run //software/embedded/ansible:run_ansible --cpu=jetson_nano -- -h` +To view a list of supported arguments, run: +`bazel run //software/embedded/ansible:run_ansible --platforms=//cc_toolchain:robot -h` If desired, the `-ho`, `--hosts` argument can be replaced with `-p`, `--port`, defining a port to listen to for Announcements from hosts. @@ -101,7 +101,7 @@ This will stop the current Systemd services, replace and restart them. Binaries This will trigger motor calibration meaning the wheels may spin. Please elevate the robot so the wheels are not touching the ground for proper calibration. -`bazel run //software/embedded/ansible:run_ansible --cpu=jetson_nano --//software/embedded:host_platform= -- --playbook deploy_robot_software.yml --hosts --ssh_pass ` +`bazel run //software/embedded/ansible:run_ansible --platforms=//cc_toolchain:robot --//software/embedded:host_platform= -- --playbook deploy_robot_software.yml --hosts --ssh_pass ` * \ is the host platform on the robot (either `PI` or `NANO`) * is the IP address of the robot * is the password of the `robot` user account @@ -119,11 +119,11 @@ Example: Flashing robots 1, 4, and 7 that have a Raspberry Pi ## Flashing the powerboard -This will flash powerloop, the current firmware in `software/power/`, onto the power board. It will prompt the user into setting the powerboard into bootloader mode by holding the boot button (left if looking from the back of the robot) and pressing the reset button (right if looking from the back of the robot), then releasing the reset button first, then the boot button. Once the board is flashed, pressing the reset button after to use the new firmware. +This will flash powerloop, the current firmware in `software/power/`, onto the power board. It will prompt the user into setting the powerboard into bootloader mode by holding the boot button (left if looking from the back of the robot) and pressing the reset button (right if looking from the back of the robot), then releasing the reset button first, then the boot button. Once the board is flashed, pressing the reset button after to use the new firmware. Looking from the back of the robot the reset and boot buttons are on right side of the battery holder on the lowest board with the reset being on the left and the boot on the right. Warning it may kick/chip when pressed. -`bazel run //software/embedded/ansible:run_ansible --cpu=jetson_nano -- --playbook deploy_powerboard.yml --hosts --ssh_pass ` +`bazel run //software/embedded/ansible:run_ansible --platforms=//cc_toolchain:robot -- --playbook deploy_powerboard.yml --hosts --ssh_pass ` ## Setting up the embedded host @@ -133,11 +133,11 @@ This section refers to setting up the computer on the robot for the first time. ### Jetson Nano -`bazel run //software/embedded/ansible:run_ansible --cpu=jetson_nano --//software/embedded:host_platform=NANO -- --playbook setup_nano.yml --hosts --ssh_pass ` +`bazel run //software/embedded/ansible:run_ansible --platforms=//cc_toolchain:robot --//software/embedded:host_platform=NANO -- --playbook setup_nano.yml --hosts --ssh_pass ` ### Raspberry Pi -`bazel run //software/embedded/ansible:run_ansible --cpu=jetson_nano --//software/embedded:host_platform=PI -- --playbook setup_raspberry_pi.yml --hosts --ssh_pass ` +`bazel run //software/embedded/ansible:run_ansible --platforms=//cc_toolchain:robot --//software/embedded:host_platform=PI -- --playbook setup_raspberry_pi.yml --hosts --ssh_pass ` ## Robot Diagnostics @@ -164,7 +164,7 @@ Runs the robot auto test fixture on a robot through Ansible, which tests the mot From Software/src: -`bazel run //software/embedded/ansible:run_ansible --//software/embedded:host_platform= --cpu=jetson_nano -- --playbook robot_auto_test_playbook.yml --hosts --ssh_pass ` +`bazel run //software/embedded/ansible:run_ansible --//software/embedded:host_platform= --platforms=//cc_toolchain:robot -- --playbook robot_auto_test_playbook.yml --hosts --ssh_pass ` * replace the \ with the target platform for the robot (either `PI` or `NANO`) * replace the \ with the actual ip address of the jetson nano for the ssh connection. * replace the with the actual password for the jetson nano for the ssh connection. diff --git a/environment_setup/setup_software.sh b/environment_setup/setup_software.sh index e38c51d1ea..422439bb77 100755 --- a/environment_setup/setup_software.sh +++ b/environment_setup/setup_software.sh @@ -11,12 +11,6 @@ # unit tests #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~# -print_status_msg () { - echo "================================================================" - echo $1 - echo "================================================================" -} - # Save the parent dir of this so we can always run commands relative to the # location of this script, no matter where it is called from. This # helps prevent bugs and odd behaviour if this script is run through a symlink @@ -24,6 +18,11 @@ print_status_msg () { CURR_DIR=$(dirname -- "$(readlink -f -- "$BASH_SOURCE")") cd "$CURR_DIR" || exit +source util.sh + +arch=$(uname -m) +print_status_msg "Detected architecture: ${arch}" + print_status_msg "Installing Utilities and Dependencies" sudo apt-get update @@ -49,10 +48,10 @@ host_software_packages=( codespell # Fixes typos curl default-jdk # Needed for Bazel to run properly - gcc-9 # We use gcc 9.3.0 + gcc-10 # Full system compiles with gcc 10 libstdc++6-9-dbg git # required for build - g++-9 + g++-10 kcachegrind # This lets us view the profiles output by callgrind libeigen3-dev # A math / numerical library used for things like linear regression libprotobuf-dev @@ -62,9 +61,9 @@ host_software_packages=( protobuf-compiler # This is required for the "NanoPb" library, which does not # properly manage this as a bazel dependency, so we have # to manually install it ourselves - python3.10 # Python 3 - python3.10-dev # Python 3 headers - python3.10-venv # Virtual Environment + python3.12 # Python 3 + python3.12-dev # Python 3 headers + python3.12-venv # Virtual Environment python3-pip # Required for bazel to install python dependencies for build targets python3-protobuf # This is required for the "NanoPb" library, which does not # properly manage this as a bazel dependency, so we have @@ -92,12 +91,25 @@ if [[ $(lsb_release -rs) == "20.04" ]]; then host_software_packages+=(libncurses5) # This fixes missing headers by notifying the linker - ldconfig + sudo ldconfig fi -if [[ $(lsb_release -rs) == "22.04" ]]; then - wget -nc https://github.com/UBC-Thunderbots/Software-External-Dependencies/blob/main/85-brltty.rules -O /tmp/85-brltty.rules - sudo mv /tmp/85-brltty.rules /usr/lib/udev/rules.d/85-brltty.rules +# Clear the download cache +rm -rf /tmp/tbots_download_cache +mkdir /tmp/tbots_download_cache + +if [[ $(lsb_release -rs) == "22.04" ]] || [[ $(lsb_release -rs) == "24.04" ]]; then + # This is required because a Braille TTY device that Linux provides a driver for conflicts with the ESP32 + wget -nc https://github.com/UBC-Thunderbots/Software-External-Dependencies/blob/main/85-brltty.rules -O /tmp/tbots_download_cache/85-brltty.rules + sudo mv /tmp/tbots_download_cache/85-brltty.rules /usr/lib/udev/rules.d/85-brltty.rules +fi + +virtualenv_opt_args="" +if [[ $(lsb_release -rs) == "24.04" ]]; then + host_software_packages+=(python3-pyqt6) + host_software_packages+=(pyqt6-dev-tools) + + virtualenv_opt_args="--system-site-packages" fi if ! sudo apt-get install "${host_software_packages[@]}" -y ; then @@ -111,14 +123,14 @@ print_status_msg "Setting Up Virtual Python Environment" # delete tbotspython first sudo rm -rf /opt/tbotspython -if ! curl -sS https://bootstrap.pypa.io/get-pip.py | sudo /usr/bin/python3.10 ; then - print_status_msg "Error: Installing pip failed" +if ! sudo /usr/bin/python3.12 -m venv /opt/tbotspython $virtualenv_opt_args ; then + print_status_msg "Error: Setting up virtual environment failed" exit 1 fi -if ! sudo /usr/bin/python3.10 -m venv /opt/tbotspython ; then - print_status_msg "Error: Setting up virtual environment failed" - exit 1 +if [[ $(lsb_release -rs) == "20.04" ]] || [[ $(lsb_release -rs) == "22.04" ]]; then + # Install pip if it is not a system-managed package + sudo /usr/bin/python3.12 -m ensurepip fi if ! sudo /opt/tbotspython/bin/python3 -m pip install --upgrade pip ; then @@ -134,32 +146,23 @@ if [[ $(lsb_release -rs) == "22.04" ]]; then sudo /opt/tbotspython/bin/pip3 install -r ubuntu22_requirements.txt fi -print_status_msg "Done Setting Up Virtual Python Environment" -print_status_msg "Fetching game controller" +if [[ $(lsb_release -rs) == "24.04" ]]; then + sudo /opt/tbotspython/bin/pip3 install -r ubuntu24_requirements.txt +fi sudo chown -R $USER:$USER /opt/tbotspython -sudo wget -N https://github.com/RoboCup-SSL/ssl-game-controller/releases/download/v2.15.2/ssl-game-controller_v2.15.2_linux_amd64 -O /opt/tbotspython/gamecontroller -sudo chmod +x /opt/tbotspython/gamecontroller + +print_status_msg "Done Setting Up Virtual Python Environment" +print_status_msg "Fetching game controller" +install_gamecontroller $arch print_status_msg "Setting up TIGERS AutoRef" -print_status_msg "Installing TIGERS dependency: Java 17" -sudo wget -N https://download.oracle.com/java/17/archive/jdk-17.0.5_linux-x64_bin.deb -O /tmp/jdk-17.0.5.deb -sudo apt install /tmp/./jdk-17.0.5.deb +print_status_msg "Installing TIGERS dependency: Java 21" +install_java $arch print_status_msg "Compiling TIGERS AutoRef" -sudo wget -N https://github.com/TIGERs-Mannheim/AutoReferee/archive/refs/heads/autoref-ci.zip -O /tmp/autoref-ci.zip -unzip -q -o -d /tmp/ /tmp/autoref-ci.zip -touch /tmp/AutoReferee-autoref-ci/.git # a hacky way to make gradle happy when it tries to find a dependency - -if ! /tmp/AutoReferee-autoref-ci/./gradlew installDist -p /tmp/AutoReferee-autoref-ci/ -Dorg.gradle.java.home=/usr/lib/jvm/jdk-17/; then - print_status_msg "Building TIGERS AutoRef failed. Downloading mirror" - - wget https://github.com/UBC-Thunderbots/AutoReferee/releases/download/autoref-ci/autoReferee.tar.gz -O /tmp/autoReferee.tar.gz - tar -xzf /tmp/autoReferee.tar.gz -C /opt/tbotspython/ -else - cp -r /tmp/AutoReferee-autoref-ci/build/install/autoReferee/ /opt/tbotspython/autoReferee -fi +install_autoref $arch sudo chmod +x "$CURR_DIR/../src/software/autoref/run_autoref.sh" sudo cp "$CURR_DIR/../src/software/autoref/DIV_B.txt" "/opt/tbotspython/autoReferee/config/geometry/DIV_B.txt" @@ -169,16 +172,14 @@ print_status_msg "Finished setting up AutoRef" # Install Bazel print_status_msg "Installing Bazel" -# Uninstall Bazel first -sudo rm -rf $HOME/.bazel - -# Adapted from https://docs.bazel.build/versions/main/install-ubuntu.html#install-with-installer-ubuntu -sudo wget -nc https://github.com/bazelbuild/bazel/releases/download/5.4.0/bazel-5.4.0-installer-linux-x86_64.sh -O /tmp/bazel-installer.sh -sudo chmod +x /tmp/bazel-installer.sh -sudo /tmp/bazel-installer.sh --bin=/usr/bin --base=$HOME/.bazel -echo "source ${HOME}/.bazel/bin/bazel-complete.bash" >> ~/.bashrc +install_bazel $arch print_status_msg "Done Installing Bazel" + +print_status_msg "Install clang-format" +install_clang_format $arch +print_status_msg "Done installing clang-format" + print_status_msg "Setting Up PlatformIO" # setup platformio to compile arduino code @@ -197,11 +198,16 @@ sudo service udev restart sudo usermod -a -G dialout $USER # install PlatformIO to global environment -if ! sudo /usr/bin/python3.10 -m pip install platformio==6.1.13; then +wget -O /tmp/tbots_download_cache/get-platformio.py https://raw.githubusercontent.com/platformio/platformio-core-installer/master/get-platformio.py +if ! /usr/bin/python3.12 /tmp/tbots_download_cache/./get-platformio.py; then print_status_msg "Error: Installing PlatformIO failed" exit 1 fi +# link platformio to /usr/local/bin so that bazel can find it +sudo rm /usr/local/bin/platformio +sudo ln -s ~/.platformio/penv/bin/platformio /usr/local/bin/platformio + print_status_msg "Done PlatformIO Setup" print_status_msg "Done Software Setup, please reboot for changes to take place" diff --git a/environment_setup/ubuntu20_requirements.txt b/environment_setup/ubuntu20_requirements.txt index 05af883b46..e521b08ed0 100644 --- a/environment_setup/ubuntu20_requirements.txt +++ b/environment_setup/ubuntu20_requirements.txt @@ -1,12 +1,10 @@ -protobuf==3.20.2 pyqtgraph==0.13.7 -pyqtdarktheme==2.1.0 -pyqt6==6.5.0 -PyQt6-Qt6==6.5.0 +pyqt6==6.6.1 +PyQt6-Qt6==6.6.1 thefuzz==0.19.0 iterfzf==0.5.0.20.0 -python-Levenshtein==0.12.2 +python-Levenshtein==0.25.1 psutil==5.9.0 PyOpenGL==3.1.6 -numpy==1.24.4 +qt-material==2.12 ruff==0.5.5 diff --git a/environment_setup/ubuntu22_requirements.txt b/environment_setup/ubuntu22_requirements.txt index 05af883b46..3a9e4d6385 100644 --- a/environment_setup/ubuntu22_requirements.txt +++ b/environment_setup/ubuntu22_requirements.txt @@ -1,12 +1,11 @@ -protobuf==3.20.2 pyqtgraph==0.13.7 -pyqtdarktheme==2.1.0 -pyqt6==6.5.0 -PyQt6-Qt6==6.5.0 +pyqt6==6.6.1 +PyQt6-Qt6==6.6.1 thefuzz==0.19.0 iterfzf==0.5.0.20.0 -python-Levenshtein==0.12.2 +python-Levenshtein==0.25.1 psutil==5.9.0 PyOpenGL==3.1.6 -numpy==1.24.4 +numpy==1.26.4 +qt-material==2.12 ruff==0.5.5 diff --git a/environment_setup/ubuntu24_requirements.txt b/environment_setup/ubuntu24_requirements.txt new file mode 100644 index 0000000000..983fcdda89 --- /dev/null +++ b/environment_setup/ubuntu24_requirements.txt @@ -0,0 +1,8 @@ +pyqtgraph==0.13.7 +thefuzz==0.19.0 +iterfzf==0.5.0.20.0 +python-Levenshtein==0.25.1 +psutil==5.9.0 +PyOpenGL==3.1.6 +qt-material==2.12 +ruff==0.5.5 diff --git a/environment_setup/util.sh b/environment_setup/util.sh new file mode 100755 index 0000000000..e72046ad56 --- /dev/null +++ b/environment_setup/util.sh @@ -0,0 +1,91 @@ +install_autoref() { + autoref_commit=b30660b78728c3ce159de8ae096181a1ec52e9ba + sudo wget -N https://github.com/TIGERs-Mannheim/AutoReferee/archive/${autoref_commit}.zip -O /tmp/tbots_download_cache/autoReferee.zip + unzip -q -o -d /tmp/tbots_download_cache/ /tmp/tbots_download_cache/autoReferee.zip + + /tmp/tbots_download_cache/AutoReferee-${autoref_commit}/./gradlew installDist -p /tmp/tbots_download_cache/AutoReferee-${autoref_commit} -Dorg.gradle.java.home=/opt/tbotspython/bin/jdk + mv /tmp/tbots_download_cache/AutoReferee-${autoref_commit}/build/install/autoReferee /opt/tbotspython/ +} + +install_bazel() { + download=https://github.com/bazelbuild/bazel/releases/download/5.4.0/bazel-5.4.0-linux-arm64 + + if is_x86 $1; then + download=https://github.com/bazelbuild/bazel/releases/download/5.4.0/bazel-5.4.0-linux-x86_64 + fi + + wget -nc $download -O /tmp/tbots_download_cache/bazel + sudo mv /tmp/tbots_download_cache/bazel /usr/bin/bazel + sudo chmod +x /usr/bin/bazel +} + +install_clang_format() { + download=https://github.com/llvm/llvm-project/releases/download/llvmorg-10.0.0/clang+llvm-10.0.0-aarch64-linux-gnu.tar.xz + clang_format_path=/tmp/tbots_download_cache/clang+llvm-10.0.0-aarch64-linux-gnu/bin/clang-format + + if is_x86 $1; then + download=https://github.com/llvm/llvm-project/releases/download/llvmorg-10.0.0/clang+llvm-10.0.0-x86_64-linux-gnu-ubuntu-18.04.tar.xz + clang_format_path=/tmp/tbots_download_cache/clang+llvm-10.0.0-x86_64-linux-gnu-ubuntu-18.04/bin/clang-format + fi + + wget $download -O /tmp/tbots_download_cache/clang.tar.xz + tar -xf /tmp/tbots_download_cache/clang.tar.xz -C /tmp/tbots_download_cache/ + sudo cp $clang_format_path /opt/tbotspython/bin/clang-format +} + +install_gamecontroller () { + # TODO(#3335): Whenever we deprecate Ubuntu 20.04, we can just grab the latest version of the SSL game controller + # binary from the releases page. This is a workaround since the latest version of the game controller is compiled + # with a newer GLIBC version than what is available on Ubuntu 20.04. + go_arch=arm64 + if is_x86 $1; then + go_arch=amd64 + fi + sudo wget -N https://go.dev/dl/go1.23.0.linux-${go_arch}.tar.gz -O /tmp/tbots_download_cache/go.tar.gz + tar -C /tmp/tbots_download_cache -xf /tmp/tbots_download_cache/go.tar.gz + export PATH=$PATH:/tmp/tbots_download_cache/go/bin + sudo wget -N https://github.com/RoboCup-SSL/ssl-game-controller/archive/refs/tags/v3.12.3.zip -O /tmp/tbots_download_cache/ssl-game-controller.zip + unzip -q -o -d /tmp/tbots_download_cache/ /tmp/tbots_download_cache/ssl-game-controller.zip + cd /tmp/tbots_download_cache/ssl-game-controller-3.12.3 + + # Installing nvm + wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash + export NVM_DIR="$HOME/.nvm" + [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm + [ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion + nvm install 20 + + make install + go build cmd/ssl-game-controller/main.go + sudo mv main /opt/tbotspython/gamecontroller + sudo chmod +x /opt/tbotspython/gamecontroller + + cd - + sudo rm -rf /tmp/tbots_download_cache/ssl-game-controller-3.12.3 + sudo rm -rf /tmp/tbots_download_cache/go +} + +install_java () { + java_home="" + java_download=https://download.oracle.com/java/21/latest/jdk-21_linux-aarch64_bin.tar.gz + if is_x86 $1; then + java_download=https://download.oracle.com/java/21/latest/jdk-21_linux-x64_bin.tar.gz + fi + sudo wget -N $java_download -O /tmp/tbots_download_cache/jdk-21.tar.gz + tar -xzf /tmp/tbots_download_cache/jdk-21.tar.gz -C /opt/tbotspython/ + mv /opt/tbotspython/jdk-21* /opt/tbotspython/bin/jdk +} + +is_x86() { + if [[ $1 == "x86_64" ]]; then + return 0 + else + return 1 + fi +} + +print_status_msg () { + echo "================================================================" + echo $1 + echo "================================================================" +} diff --git a/scripts/clang-format-10.0 b/scripts/clang-format-10.0 deleted file mode 100755 index c3b9422c90..0000000000 Binary files a/scripts/clang-format-10.0 and /dev/null differ diff --git a/scripts/lint_and_format.sh b/scripts/lint_and_format.sh index 8982f4ff5a..0f6fc83187 100755 --- a/scripts/lint_and_format.sh +++ b/scripts/lint_and_format.sh @@ -10,6 +10,9 @@ export CLANG_VERSION=10.0 # The directory this script is in CURR_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +# The path to clang-format +export CLANG_BIN=/opt/tbotspython/bin/clang-format + # The root bazel directory BAZEL_ROOT_DIR="$CURR_DIR/../src" @@ -33,7 +36,7 @@ function run_clang_format () { # clang-format as arguments # We remove the last -o flag from the extension string find $CURR_DIR/../src/ ${EXTENSION_STRING::-2} \ - | xargs -I{} -n1000 $CURR_DIR/clang-format-$CLANG_VERSION -i -style=file + | xargs -I{} -n1000 $CLANG_BIN -i -style=file if [[ "$?" != 0 ]]; then printf "\n***Failed to run clang-format over all files!***\n\n" diff --git a/src/.bazelrc b/src/.bazelrc index 1df5a1234b..4dfa7f43a5 100644 --- a/src/.bazelrc +++ b/src/.bazelrc @@ -10,7 +10,7 @@ test --test_output=all build --crosstool_top=//cc_toolchain:toolchain # Add warnings to Thunderbots code only -build --per_file_copt=//proto/message_translation/.*,//proto/primitive/.*,//software/.*,//shared/.*@-Wall,-Wextra,-Wconversion,-Wno-unused-parameter,-Wno-deprecated,-Werror +build --per_file_copt=//proto/.*,//proto/message_translation/.*,//proto/primitive/.*,//software/.*,//shared/.*@-Wall,-Wextra,-Wconversion,-Wno-unused-parameter,-Wno-deprecated,-Werror,-Wno-deprecated-declarations # Warn variable length arrays only when compiling cpp build --per_file_copt=.*\.cpp@-Wvla @@ -31,5 +31,5 @@ build --test_env=XDG_RUNTIME_DIR build --test_env=DISPLAY # Setup python bin/lib to point to our venv -build --action_env=PYTHON_BIN_PATH=/opt/tbotspython/bin/python3.10 -build --action_env=PYTHON_LIB_PATH=/opt/tbotspython/lib/python3.10 +build --action_env=PYTHON_BIN_PATH=/opt/tbotspython/bin/python3.12 +build --action_env=PYTHON_LIB_PATH=/opt/tbotspython/lib/python3.12 diff --git a/src/WORKSPACE b/src/WORKSPACE index 5cd0c12743..1814824150 100644 --- a/src/WORKSPACE +++ b/src/WORKSPACE @@ -104,9 +104,9 @@ http_archive( http_archive( name = "g3log", build_file = "@//extlibs:g3log.BUILD", - sha256 = "176fcf4e1634aba425549c32f76426d7976ab6973370785fd6b76986e9f7b20e", - strip_prefix = "g3log-1.3.3", - url = "https://github.com/KjellKod/g3log/archive/1.3.3.zip", + sha256 = "2177e6dfd86fa7465c44c8ef5c3b6ab98ffc94e1130355d6982f7d886cb7bec9", + strip_prefix = "g3log-2.4", + url = "https://github.com/KjellKod/g3log/archive/refs/tags/2.4.zip", ) http_archive( @@ -142,9 +142,9 @@ protobuf_deps() git_repository( name = "com_github_nelhage_rules_boost", - commit = "7332c6cf2afb2642f53bc23f9b4d9c1817318685", + commit = "58be4e7e851d19e9ba14ced7bdba6fc8895af1d3", remote = "https://github.com/nelhage/rules_boost", - shallow_since = "1606097530 -0500", + shallow_since = "1724946929 +0200", ) git_repository( @@ -215,8 +215,14 @@ git_repository( ) new_local_repository( - name = "linux_gcc", - build_file = "@//extlibs:linux_gcc.BUILD", + name = "linux_k8_gcc", + build_file = "@//extlibs:linux_k8_gcc.BUILD", + path = "/", +) + +new_local_repository( + name = "linux_aarch64_gcc", + build_file = "@//extlibs:linux_aarch64_gcc.BUILD", path = "/", ) @@ -228,8 +234,8 @@ new_local_repository( ) http_archive( - name = "jetson_nano_gcc", - build_file = "@//extlibs:jetson_nano_gcc.BUILD", + name = "k8_jetson_nano_cross_compile_gcc", + build_file = "@//extlibs:k8_jetson_nano_cross_compile_gcc.BUILD", sha256 = "73eed74e593e2267504efbcf3678918bb22409ab7afa3dc7c135d2c6790c2345", strip_prefix = "gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu", urls = [ @@ -332,9 +338,9 @@ http_archive( http_archive( name = "pybind11", build_file = "@pybind11_bazel//:pybind11.BUILD", - sha256 = "1c6e0141f7092867c5bf388bc3acdb2689ed49f59c3977651394c6c87ae88232", - strip_prefix = "pybind11-2.9.0", - urls = ["https://github.com/pybind/pybind11/archive/refs/tags/v2.9.0.zip"], + sha256 = "411f77380c43798506b39ec594fc7f2b532a13c4db674fcf2b1ca344efaefb68", + strip_prefix = "pybind11-2.12.0", + urls = ["https://github.com/pybind/pybind11/archive/refs/tags/v2.12.0.zip"], ) load("@pybind11_bazel//:python_configure.bzl", "python_configure") @@ -386,3 +392,9 @@ new_git_repository( remote = "https://github.com/wolfpld/tracy.git", shallow_since = "1697482622 +0200", ) + +register_toolchains( + "//cc_toolchain:cc_toolchain_for_k8_jetson_nano_cross_compile", + "//cc_toolchain:cc_toolchain_for_k8", + "//cc_toolchain:cc_toolchain_for_aarch64", +) diff --git a/src/cc_toolchain/BUILD b/src/cc_toolchain/BUILD index 60c869dfed..d5396df343 100644 --- a/src/cc_toolchain/BUILD +++ b/src/cc_toolchain/BUILD @@ -1,46 +1,69 @@ package(default_visibility = ["//visibility:public"]) -load(":cc_toolchain_config.bzl", "cc_toolchain_config_jetson_nano", "cc_toolchain_config_k8") +load( + ":cc_toolchain_config.bzl", + "cc_toolchain_config_fullsystem", + "cc_toolchain_config_k8_jetson_nano_cross_compile", + "make_builtin_include_directories", +) # Create environments for each CPU this toolchain supports environment(name = "k8") -environment(name = "jetson_nano") +environment(name = "k8_jetson_nano_cross_compile") + +environment(name = "aarch64") environment_group( name = "cpus", defaults = [ + ":aarch64", ":k8", - ":jetson_nano", + ":k8_jetson_nano_cross_compile", ], environments = [ + ":aarch64", ":k8", - ":jetson_nano", + ":k8_jetson_nano_cross_compile", ], ) +config_setting( + name = "cpu_aarch64", + values = {"cpu": "aarch64"}, +) + config_setting( name = "cpu_k8", values = {"cpu": "k8"}, ) config_setting( - name = "cpu_jetson_nano", - values = {"cpu": "jetson_nano"}, + name = "cpu_k8_jetson_nano_cross_compile", + values = {"cpu": "k8_jetson_nano_cross_compile"}, +) + +platform( + name = "robot", + constraint_values = [ + "@platforms//cpu:aarch64", + "@platforms//os:linux", + ], ) # This represents a mapping of CPU -> Compiler To Use -# The CPU can be chosen by using `--cpu` as a bazel flag (ex. `--cpu=jetson_nano`) -# otherwise it will default to using whatever CPU is in the system doing the compiling cc_toolchain_suite( name = "toolchain", toolchains = { # k8 is any x86 system - "k8": "cc_toolchain_linux_gcc", - "k8|compiler": "cc_toolchain_linux_gcc", + "k8": "cc_toolchain_linux_k8_gcc", + "k8|compiler": "cc_toolchain_linux_k8_gcc", + # aarch64 is for ARM64 systems and the robot + "aarch64": "cc_toolchain_linux_aarch64_gcc", + "aarch64|compiler": "cc_toolchain_linux_aarch64_gcc", # jetson nano 4GB system - "jetson_nano": "cc_toolchain_jetson_nano", - "jetson_nano|compiler": "cc_toolchain_jetson_nano", + "k8_jetson_nano_cross_compile": "cc_toolchain_k8_jetson_nano_cross_compile", + "k8_jetson_nano_cross_compile|compiler": "cc_toolchain_k8_jetson_nano_cross_compile", }, ) @@ -50,10 +73,10 @@ filegroup( ) filegroup( - name = "jetson_nano_everything", + name = "k8_jetson_nano_cross_compile_everything", srcs = [ - "@jetson_nano_gcc//:everything", - ] + glob(["wrapper/jetson_nano_*"]), + "@k8_jetson_nano_cross_compile_gcc//:everything", + ] + glob(["wrapper/k8_jetson_nano_cross_compile_*"]), ) filegroup( @@ -62,71 +85,95 @@ filegroup( ) filegroup( - name = "linux_gcc_all", + name = "linux_k8_gcc_all", + srcs = [ + ":linux_gcc_wrapper", + "@linux_k8_gcc//:includes", + "@linux_k8_gcc//:libs", + "@linux_k8_gcc//:runtime_libs", + "@linux_k8_gcc//:static_libs", + ], +) + +filegroup( + name = "linux_aarch64_gcc_all", srcs = [ ":linux_gcc_wrapper", - "@linux_gcc//:includes", - "@linux_gcc//:libs", - "@linux_gcc//:runtime_libs", - "@linux_gcc//:static_libs", + "@linux_aarch64_gcc//:includes", + "@linux_aarch64_gcc//:libs", + "@linux_aarch64_gcc//:runtime_libs", + "@linux_aarch64_gcc//:static_libs", ], ) -cc_toolchain_config_k8( - name = "linux_gcc", +cc_toolchain_config_fullsystem( + name = "linux_k8_gcc", builtin_include_directories = [ "/usr/lib/gcc/x86_64-linux-gnu/", - "/usr/include/", - "/usr/local/include/", - "/usr/lib/gcc/c++/*/include/", - ], - cpu = "k8", + ] + make_builtin_include_directories(), + host_system_name = "k8", target_cpu = "k8", target_system_name = "k8", - tool_paths = { - "ar": "/usr/bin/ar", - "cpp": "/usr/bin/cpp", - "dwp": "/usr/bin/dwp", - "gcc": "wrapper/linux_gcc", - "gcov": "/usr/bin/gcov", - "ld": "/usr/bin/ld", - "nm": "/usr/bin/nm", - "objcopy": "/usr/bin/objcopy", - "objdump": "/usr/bin/objdump", - "strip": "/usr/bin/strip", - }, - toolchain_identifier = "linux_gcc-k8", + toolchain_identifier = "linux_k8_gcc", +) + +cc_toolchain_config_fullsystem( + name = "linux_aarch64_gcc", + builtin_include_directories = [ + "/usr/lib/gcc/aarch64-linux-gnu/", + ] + make_builtin_include_directories(), + host_system_name = "aarch64", + target_cpu = "aarch64", + target_system_name = "aarch64", + toolchain_identifier = "linux_aarch64_gcc", ) cc_toolchain( - name = "cc_toolchain_linux_gcc", - all_files = ":linux_gcc_all", - ar_files = ":linux_gcc_all", - as_files = ":linux_gcc_all", - compiler_files = ":linux_gcc_all", - dwp_files = ":linux_gcc_all", - dynamic_runtime_lib = "@linux_gcc//:runtime_libs", - linker_files = ":linux_gcc_all", - objcopy_files = ":linux_gcc_all", - static_runtime_lib = "@linux_gcc//:static_libs", - strip_files = ":linux_gcc_all", + name = "cc_toolchain_linux_k8_gcc", + all_files = ":linux_k8_gcc_all", + ar_files = ":linux_k8_gcc_all", + as_files = ":linux_k8_gcc_all", + compiler_files = ":linux_k8_gcc_all", + dwp_files = ":linux_k8_gcc_all", + dynamic_runtime_lib = "@linux_k8_gcc//:runtime_libs", + linker_files = ":linux_k8_gcc_all", + objcopy_files = ":linux_k8_gcc_all", + static_runtime_lib = "@linux_k8_gcc//:static_libs", + strip_files = ":linux_k8_gcc_all", supports_param_files = True, # We add this tag to circumvent a bug in the CLion bazel plugin. It should be removed # when possible # https://github.com/bazelbuild/intellij/issues/486 tags = ["no-ide"], - toolchain_config = ":linux_gcc", - toolchain_identifier = "k8_gcc-x86_64", + toolchain_config = ":linux_k8_gcc", + toolchain_identifier = "k8_gcc", ) cc_toolchain( - name = "cc_toolchain_jetson_nano", - all_files = ":jetson_nano_everything", - ar_files = ":jetson_nano_everything", - as_files = ":jetson_nano_everything", - compiler_files = ":jetson_nano_everything", + name = "cc_toolchain_linux_aarch64_gcc", + all_files = ":linux_aarch64_gcc_all", + ar_files = ":linux_aarch64_gcc_all", + as_files = ":linux_aarch64_gcc_all", + compiler_files = ":linux_aarch64_gcc_all", + dwp_files = ":linux_aarch64_gcc_all", + dynamic_runtime_lib = "@linux_aarch64_gcc//:runtime_libs", + linker_files = ":linux_aarch64_gcc_all", + objcopy_files = ":linux_aarch64_gcc_all", + static_runtime_lib = "@linux_aarch64_gcc//:static_libs", + strip_files = ":linux_aarch64_gcc_all", + supports_param_files = True, + toolchain_config = ":linux_aarch64_gcc", + toolchain_identifier = "aarch64_gcc", +) + +cc_toolchain( + name = "cc_toolchain_k8_jetson_nano_cross_compile", + all_files = ":k8_jetson_nano_cross_compile_everything", + ar_files = ":k8_jetson_nano_cross_compile_everything", + as_files = ":k8_jetson_nano_cross_compile_everything", + compiler_files = ":k8_jetson_nano_cross_compile_everything", dwp_files = ":empty", - linker_files = ":jetson_nano_everything", + linker_files = ":k8_jetson_nano_cross_compile_everything", objcopy_files = ":empty", strip_files = ":empty", supports_param_files = 0, @@ -134,30 +181,71 @@ cc_toolchain( # when possible # https://github.com/bazelbuild/intellij/issues/486 tags = ["no-ide"], - toolchain_config = ":gcc-jetson_nano", - toolchain_identifier = "gcc-jetson_nano", + toolchain_config = ":gcc_k8_jetson_nano_cross_compile", + toolchain_identifier = "gcc-k8-jetson-nano-cross-compile", ) -cc_toolchain_config_jetson_nano( - name = "gcc-jetson_nano", +cc_toolchain_config_k8_jetson_nano_cross_compile( + name = "gcc_k8_jetson_nano_cross_compile", builtin_include_directories = [ - "external/jetson_nano_gcc/include/", - "external/jetson_nano_gcc/aarch64-linux-gnu/include/", - "external/jetson_nano_gcc/aarch64-linux-gnu/libc/lib/", - "external/jetson_nano_gcc/aarch64-linux-gnu/libc/usr/include/", + "external/k8_jetson_nano_cross_compile_gcc/include/", + "external/k8_jetson_nano_cross_compile_gcc/aarch64-linux-gnu/include/", + "external/k8_jetson_nano_cross_compile_gcc/aarch64-linux-gnu/libc/lib/", + "external/k8_jetson_nano_cross_compile_gcc/aarch64-linux-gnu/libc/usr/include/", ], - cpu = "jetson_nano", tool_paths = { - "ar": "wrapper/jetson_nano_ar", - "cpp": "wrapper/jetson_nano_cpp", - "dwp": "wrapper/jetson_nano_dwp", - "gcc": "wrapper/jetson_nano_gcc", - "gcov": "wrapper/jetson_nano_gcov", - "ld": "wrapper/jetson_nano_ld", - "nm": "wrapper/jetson_nano_nm", - "objcopy": "wrapper/jetson_nano_objcopy", - "objdump": "wrapper/jetson_nano_objdump", - "strip": "wrapper/jetson_nano_strip", + "ar": "wrapper/k8_jetson_nano_cross_compile_ar", + "cpp": "wrapper/k8_jetson_nano_cross_compile_cpp", + "dwp": "wrapper/k8_jetson_nano_cross_compile_dwp", + "gcc": "wrapper/k8_jetson_nano_cross_compile_gcc", + "gcov": "wrapper/k8_jetson_nano_cross_compile_gcov", + "ld": "wrapper/k8_jetson_nano_cross_compile_ld", + "nm": "wrapper/k8_jetson_nano_cross_compile_nm", + "objcopy": "wrapper/k8_jetson_nano_cross_compile_objcopy", + "objdump": "wrapper/k8_jetson_nano_cross_compile_objdump", + "strip": "wrapper/k8_jetson_nano_cross_compile_strip", }, - toolchain_identifier = "gcc-jetson_nano", + toolchain_identifier = "gcc-k8-jetson_nano-cross-compile", +) + +toolchain( + name = "cc_toolchain_for_k8_jetson_nano_cross_compile", + exec_compatible_with = [ + "@platforms//cpu:x86_64", + "@platforms//os:linux", + ], + target_compatible_with = [ + "@platforms//cpu:aarch64", + "@platforms//os:linux", + ], + toolchain = ":cc_toolchain_k8_jetson_nano_cross_compile", + toolchain_type = "@bazel_tools//tools/cpp:toolchain_type", +) + +toolchain( + name = "cc_toolchain_for_k8", + exec_compatible_with = [ + "@platforms//os:linux", + "@platforms//cpu:x86_64", + ], + target_compatible_with = [ + "@platforms//os:linux", + "@platforms//cpu:x86_64", + ], + toolchain = ":cc_toolchain_linux_k8_gcc", + toolchain_type = "@bazel_tools//tools/cpp:toolchain_type", +) + +toolchain( + name = "cc_toolchain_for_aarch64", + exec_compatible_with = [ + "@platforms//cpu:aarch64", + "@platforms//os:linux", + ], + target_compatible_with = [ + "@platforms//cpu:aarch64", + "@platforms//os:linux", + ], + toolchain = ":cc_toolchain_linux_aarch64_gcc", + toolchain_type = "@bazel_tools//tools/cpp:toolchain_type", ) diff --git a/src/cc_toolchain/cc_toolchain_config.bzl b/src/cc_toolchain/cc_toolchain_config.bzl index 00f9e08373..1544046401 100644 --- a/src/cc_toolchain/cc_toolchain_config.bzl +++ b/src/cc_toolchain/cc_toolchain_config.bzl @@ -104,6 +104,27 @@ ALL_CPP_ACTIONS = [ ACTION_NAMES.cpp_link_nodeps_dynamic_library, ] +def make_builtin_include_directories(): + return [ + "/usr/include/", + "/usr/local/include/", + "/usr/lib/gcc/c++/*/include/", + ] + +def _make_common_toolpaths(): + return { + "ar": "/usr/bin/ar", + "cpp": "/usr/bin/cpp", + "dwp": "/usr/bin/dwp", + "gcc": "wrapper/linux_gcc", + "gcov": "/usr/bin/gcov", + "ld": "/usr/bin/ld", + "nm": "/usr/bin/nm", + "objcopy": "/usr/bin/objcopy", + "objdump": "/usr/bin/objdump", + "strip": "/usr/bin/strip", + } + def _make_common_features(ctx): result = {} @@ -401,13 +422,11 @@ def _make_common_features(ctx): return result def _linux_gcc_impl(ctx): - host_system_name = "k8" - action_configs = [] tool_paths = [ tool_path(name = name, path = path) - for name, path in ctx.attr.tool_paths.items() + for name, path in _make_common_toolpaths().items() ] common = _make_common_features(ctx) @@ -560,7 +579,7 @@ def _linux_gcc_impl(ctx): artifact_name_patterns = [], cxx_builtin_include_directories = ctx.attr.builtin_include_directories, toolchain_identifier = ctx.attr.toolchain_identifier, - host_system_name = host_system_name, + host_system_name = ctx.attr.host_system_name, target_system_name = ctx.attr.target_system_name, target_cpu = ctx.attr.target_cpu, target_libc = "libc", @@ -577,14 +596,14 @@ def _linux_gcc_impl(ctx): ), ] -cc_toolchain_config_k8 = rule( +cc_toolchain_config_fullsystem = rule( implementation = _linux_gcc_impl, attrs = { "builtin_include_directories": attr.string_list(), - "cpu": attr.string(mandatory = True, values = ["k8"]), "extra_features": attr.string_list(), "extra_no_canonical_prefixes_flags": attr.string_list(), "host_compiler_warnings": attr.string_list(), + "host_system_name": attr.string(), "host_unfiltered_compile_flags": attr.string_list(), "target_cpu": attr.string(), "target_system_name": attr.string(), @@ -595,7 +614,7 @@ cc_toolchain_config_k8 = rule( executable = True, ) -def _jetson_nano_impl(ctx): +def _k8_jetson_nano_cross_compile_impl(ctx): host_system_name = "k8" action_configs = [] @@ -708,12 +727,9 @@ def _jetson_nano_impl(ctx): ), ] -cc_toolchain_config_jetson_nano = rule( - implementation = _jetson_nano_impl, +cc_toolchain_config_k8_jetson_nano_cross_compile = rule( + implementation = _k8_jetson_nano_cross_compile_impl, attrs = { - "cpu": attr.string(mandatory = True, values = [ - "jetson_nano", - ]), "builtin_include_directories": attr.string_list(), "extra_no_canonical_prefixes_flags": attr.string_list(), "host_compiler_warnings": attr.string_list(), diff --git a/src/cc_toolchain/wrapper/jetson_nano_ar b/src/cc_toolchain/wrapper/jetson_nano_ar deleted file mode 100755 index d40a860b6e..0000000000 --- a/src/cc_toolchain/wrapper/jetson_nano_ar +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash --norc - -exec external/jetson_nano_gcc/bin/aarch64-linux-gnu-ar "$@" diff --git a/src/cc_toolchain/wrapper/jetson_nano_cpp b/src/cc_toolchain/wrapper/jetson_nano_cpp deleted file mode 100755 index aff3764d78..0000000000 --- a/src/cc_toolchain/wrapper/jetson_nano_cpp +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash --norc - -exec external/jetson_nano_gcc/bin/aarch64-linux-gnu-cpp "$@" diff --git a/src/cc_toolchain/wrapper/jetson_nano_g++ b/src/cc_toolchain/wrapper/jetson_nano_g++ deleted file mode 100755 index b8f943f7e3..0000000000 --- a/src/cc_toolchain/wrapper/jetson_nano_g++ +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash --norc - -exec external/jetson_nano_gcc/bin/aarch64-linux-gnu-g++ -Wl,--no-as-needed "$@" diff --git a/src/cc_toolchain/wrapper/jetson_nano_gcc b/src/cc_toolchain/wrapper/jetson_nano_gcc deleted file mode 100755 index 64774504ab..0000000000 --- a/src/cc_toolchain/wrapper/jetson_nano_gcc +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash --norc - -exec external/jetson_nano_gcc/bin/aarch64-linux-gnu-gcc -Wl,--no-as-needed "$@" diff --git a/src/cc_toolchain/wrapper/jetson_nano_gcov b/src/cc_toolchain/wrapper/jetson_nano_gcov deleted file mode 100755 index 7922e92416..0000000000 --- a/src/cc_toolchain/wrapper/jetson_nano_gcov +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash --norc - -exec external/jetson_nano_gcc/bin/aarch64-linux-gnu-gcov "$@" diff --git a/src/cc_toolchain/wrapper/jetson_nano_ld b/src/cc_toolchain/wrapper/jetson_nano_ld deleted file mode 100755 index 51728eeb07..0000000000 --- a/src/cc_toolchain/wrapper/jetson_nano_ld +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash --norc - -exec external/jetson_nano_gcc/bin/aarch64-linux-gnu-ld "$@" diff --git a/src/cc_toolchain/wrapper/jetson_nano_nm b/src/cc_toolchain/wrapper/jetson_nano_nm deleted file mode 100755 index 98c9a6ba28..0000000000 --- a/src/cc_toolchain/wrapper/jetson_nano_nm +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash --norc - -exec external/jetson_nano_gcc/bin/aarch64-linux-gnu-nm "$@" diff --git a/src/cc_toolchain/wrapper/jetson_nano_objcopy b/src/cc_toolchain/wrapper/jetson_nano_objcopy deleted file mode 100755 index 70ff1f0e61..0000000000 --- a/src/cc_toolchain/wrapper/jetson_nano_objcopy +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash --norc - -exec external/jetson_nano_gcc/bin/aarch64-linux-gnu-objcopy "$@" diff --git a/src/cc_toolchain/wrapper/jetson_nano_objdump b/src/cc_toolchain/wrapper/jetson_nano_objdump deleted file mode 100755 index b17ce50c8c..0000000000 --- a/src/cc_toolchain/wrapper/jetson_nano_objdump +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash --norc - -exec external/jetson_nano_gcc/bin/aarch64-linux-gnu-objdump "$@" diff --git a/src/cc_toolchain/wrapper/jetson_nano_strip b/src/cc_toolchain/wrapper/jetson_nano_strip deleted file mode 100755 index 1d67bf46c0..0000000000 --- a/src/cc_toolchain/wrapper/jetson_nano_strip +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash --norc - -exec external/jetson_nano_gcc/bin/aarch64-linux-gnu-strip "$@" diff --git a/src/cc_toolchain/wrapper/k8_jetson_nano_cross_compile_ar b/src/cc_toolchain/wrapper/k8_jetson_nano_cross_compile_ar new file mode 100755 index 0000000000..233d5e3c4c --- /dev/null +++ b/src/cc_toolchain/wrapper/k8_jetson_nano_cross_compile_ar @@ -0,0 +1,3 @@ +#!/bin/bash --norc + +exec external/k8_jetson_nano_cross_compile_gcc/bin/aarch64-linux-gnu-ar "$@" diff --git a/src/cc_toolchain/wrapper/k8_jetson_nano_cross_compile_cpp b/src/cc_toolchain/wrapper/k8_jetson_nano_cross_compile_cpp new file mode 100755 index 0000000000..8977e9e4fd --- /dev/null +++ b/src/cc_toolchain/wrapper/k8_jetson_nano_cross_compile_cpp @@ -0,0 +1,3 @@ +#!/bin/bash --norc + +exec external/k8_jetson_nano_cross_compile_gcc/bin/aarch64-linux-gnu-cpp "$@" diff --git a/src/cc_toolchain/wrapper/k8_jetson_nano_cross_compile_g++ b/src/cc_toolchain/wrapper/k8_jetson_nano_cross_compile_g++ new file mode 100755 index 0000000000..a3f3025445 --- /dev/null +++ b/src/cc_toolchain/wrapper/k8_jetson_nano_cross_compile_g++ @@ -0,0 +1,3 @@ +#!/bin/bash --norc + +exec external/k8_jetson_nano_cross_compile_gcc/bin/aarch64-linux-gnu-g++ -Wl,--no-as-needed "$@" diff --git a/src/cc_toolchain/wrapper/k8_jetson_nano_cross_compile_gcc b/src/cc_toolchain/wrapper/k8_jetson_nano_cross_compile_gcc new file mode 100755 index 0000000000..cad72ed459 --- /dev/null +++ b/src/cc_toolchain/wrapper/k8_jetson_nano_cross_compile_gcc @@ -0,0 +1,3 @@ +#!/bin/bash --norc + +exec external/k8_jetson_nano_cross_compile_gcc/bin/aarch64-linux-gnu-gcc -Wl,--no-as-needed "$@" diff --git a/src/cc_toolchain/wrapper/k8_jetson_nano_cross_compile_gcov b/src/cc_toolchain/wrapper/k8_jetson_nano_cross_compile_gcov new file mode 100755 index 0000000000..7c3616749d --- /dev/null +++ b/src/cc_toolchain/wrapper/k8_jetson_nano_cross_compile_gcov @@ -0,0 +1,3 @@ +#!/bin/bash --norc + +exec external/k8_jetson_nano_cross_compile_gcc/bin/aarch64-linux-gnu-gcov "$@" diff --git a/src/cc_toolchain/wrapper/k8_jetson_nano_cross_compile_ld b/src/cc_toolchain/wrapper/k8_jetson_nano_cross_compile_ld new file mode 100755 index 0000000000..7ed51ae2b3 --- /dev/null +++ b/src/cc_toolchain/wrapper/k8_jetson_nano_cross_compile_ld @@ -0,0 +1,3 @@ +#!/bin/bash --norc + +exec external/k8_jetson_nano_cross_compile_gcc/bin/aarch64-linux-gnu-ld "$@" diff --git a/src/cc_toolchain/wrapper/k8_jetson_nano_cross_compile_nm b/src/cc_toolchain/wrapper/k8_jetson_nano_cross_compile_nm new file mode 100755 index 0000000000..2eb52826c7 --- /dev/null +++ b/src/cc_toolchain/wrapper/k8_jetson_nano_cross_compile_nm @@ -0,0 +1,3 @@ +#!/bin/bash --norc + +exec external/k8_jetson_nano_cross_compile_gcc/bin/aarch64-linux-gnu-nm "$@" diff --git a/src/cc_toolchain/wrapper/k8_jetson_nano_cross_compile_objcopy b/src/cc_toolchain/wrapper/k8_jetson_nano_cross_compile_objcopy new file mode 100755 index 0000000000..2b324ad0cc --- /dev/null +++ b/src/cc_toolchain/wrapper/k8_jetson_nano_cross_compile_objcopy @@ -0,0 +1,3 @@ +#!/bin/bash --norc + +exec external/k8_jetson_nano_cross_compile_gcc/bin/aarch64-linux-gnu-objcopy "$@" diff --git a/src/cc_toolchain/wrapper/k8_jetson_nano_cross_compile_objdump b/src/cc_toolchain/wrapper/k8_jetson_nano_cross_compile_objdump new file mode 100755 index 0000000000..1b69911e81 --- /dev/null +++ b/src/cc_toolchain/wrapper/k8_jetson_nano_cross_compile_objdump @@ -0,0 +1,3 @@ +#!/bin/bash --norc + +exec external/k8_jetson_nano_cross_compile_gcc/bin/aarch64-linux-gnu-objdump "$@" diff --git a/src/cc_toolchain/wrapper/k8_jetson_nano_cross_compile_strip b/src/cc_toolchain/wrapper/k8_jetson_nano_cross_compile_strip new file mode 100755 index 0000000000..67a975cc89 --- /dev/null +++ b/src/cc_toolchain/wrapper/k8_jetson_nano_cross_compile_strip @@ -0,0 +1,3 @@ +#!/bin/bash --norc + +exec external/k8_jetson_nano_cross_compile_gcc/bin/aarch64-linux-gnu-strip "$@" diff --git a/src/cc_toolchain/wrapper/linux_gcc b/src/cc_toolchain/wrapper/linux_gcc index 9c27b70983..e0800abb9c 100755 --- a/src/cc_toolchain/wrapper/linux_gcc +++ b/src/cc_toolchain/wrapper/linux_gcc @@ -6,4 +6,4 @@ # only link in the direct dependencies for each shared lib, but because # bazel delays linking to the end of the build, this means some (non-direct) # dependencies of the final target will not be linked in -exec /usr/bin/gcc-9 -Wl,--no-as-needed "$@" +exec /usr/bin/gcc-10 -Wl,--no-as-needed "$@" diff --git a/src/extlibs/jetson_nano_gcc.BUILD b/src/extlibs/k8_jetson_nano_cross_compile_gcc.BUILD similarity index 100% rename from src/extlibs/jetson_nano_gcc.BUILD rename to src/extlibs/k8_jetson_nano_cross_compile_gcc.BUILD diff --git a/src/extlibs/linux_aarch64_gcc.BUILD b/src/extlibs/linux_aarch64_gcc.BUILD new file mode 100644 index 0000000000..fa986c6923 --- /dev/null +++ b/src/extlibs/linux_aarch64_gcc.BUILD @@ -0,0 +1,28 @@ +package(default_visibility = ["//visibility:public"]) + +filegroup( + name = "libs", + srcs = glob(["usr/lib/gcc/aarch64-linux-gnu/10/*.a"]), +) + +filegroup( + name = "includes", + srcs = glob([ + "usr/lib/gcc/aarch64-linux-gnu/10/include/**", + "usr/lib/gcc/aarch64-linux-gnu/10/include", + ]), +) + +filegroup( + name = "runtime_libs", + srcs = [ + "usr/lib/gcc/aarch64-linux-gnu/10/libstdc++.so", + ], +) + +filegroup( + name = "static_libs", + srcs = [ + "usr/lib/gcc/aarch64-linux-gnu/10/libstdc++.a", + ], +) diff --git a/src/extlibs/linux_gcc.BUILD b/src/extlibs/linux_gcc.BUILD deleted file mode 100644 index 0191adbe7e..0000000000 --- a/src/extlibs/linux_gcc.BUILD +++ /dev/null @@ -1,28 +0,0 @@ -package(default_visibility = ["//visibility:public"]) - -filegroup( - name = "libs", - srcs = glob(["usr/lib/gcc/x86_64-linux-gnu/9/*.a"]), -) - -filegroup( - name = "includes", - srcs = glob([ - "usr/lib/gcc/x86_64-linux-gnu/9/include/**", - "usr/lib/gcc/x86_64-linux-gnu/9/include", - ]), -) - -filegroup( - name = "runtime_libs", - srcs = [ - "usr/lib/gcc/x86_64-linux-gnu/9/libstdc++.so", - ], -) - -filegroup( - name = "static_libs", - srcs = [ - "usr/lib/gcc/x86_64-linux-gnu/9/libstdc++.a", - ], -) diff --git a/src/extlibs/linux_k8_gcc.BUILD b/src/extlibs/linux_k8_gcc.BUILD new file mode 100644 index 0000000000..5d4840e28c --- /dev/null +++ b/src/extlibs/linux_k8_gcc.BUILD @@ -0,0 +1,28 @@ +package(default_visibility = ["//visibility:public"]) + +filegroup( + name = "libs", + srcs = glob(["usr/lib/gcc/x86_64-linux-gnu/10/*.a"]), +) + +filegroup( + name = "includes", + srcs = glob([ + "usr/lib/gcc/x86_64-linux-gnu/10/include/**", + "usr/lib/gcc/x86_64-linux-gnu/10/include", + ]), +) + +filegroup( + name = "runtime_libs", + srcs = [ + "usr/lib/gcc/x86_64-linux-gnu/10/libstdc++.so", + ], +) + +filegroup( + name = "static_libs", + srcs = [ + "usr/lib/gcc/x86_64-linux-gnu/10/libstdc++.a", + ], +) diff --git a/src/extlibs/nanopb_requirements_lock.txt b/src/extlibs/nanopb_requirements_lock.txt index fad7c9e32e..13481a4ab1 100644 --- a/src/extlibs/nanopb_requirements_lock.txt +++ b/src/extlibs/nanopb_requirements_lock.txt @@ -1,5 +1,5 @@ # -# This file is autogenerated by pip-compile with Python 3.10 +# This file is autogenerated by pip-compile with Python 3.12 # by the following command: # # bazel run //extlibs:nanopb_requirements.update diff --git a/src/proto/BUILD b/src/proto/BUILD index a83817ed9a..9557086590 100644 --- a/src/proto/BUILD +++ b/src/proto/BUILD @@ -93,6 +93,7 @@ proto_library( deps = [ "@com_google_protobuf//:duration_proto", "@com_google_protobuf//:timestamp_proto", + "@com_google_protobuf//:wrappers_proto", ], ) diff --git a/src/proto/message_translation/ssl_simulation_robot_control.cpp b/src/proto/message_translation/ssl_simulation_robot_control.cpp index fe87dde214..7f1d7d998f 100644 --- a/src/proto/message_translation/ssl_simulation_robot_control.cpp +++ b/src/proto/message_translation/ssl_simulation_robot_control.cpp @@ -16,10 +16,12 @@ std::unique_ptr createRobotMoveCommand( { switch (direct_control.motor_control().drive_control_case()) { + case TbotsProto::MotorControl::DRIVE_CONTROL_NOT_SET: + break; + case TbotsProto::MotorControl::kDirectPerWheelControl: - { LOG(FATAL) << "Direct per-wheel control is not supported in simulation"; - } + break; case TbotsProto::MotorControl::kDirectVelocityControl: { diff --git a/src/proto/message_translation/tbots_protobuf.cpp b/src/proto/message_translation/tbots_protobuf.cpp index bc5623b8c5..0f780eccd9 100644 --- a/src/proto/message_translation/tbots_protobuf.cpp +++ b/src/proto/message_translation/tbots_protobuf.cpp @@ -321,8 +321,8 @@ std::unique_ptr createPlotJugglerValue( { auto plot_juggler_value_msg = std::make_unique(); double now = - static_cast(std::chrono::system_clock::now().time_since_epoch().count() / - NANOSECONDS_PER_SECOND); + static_cast(std::chrono::system_clock::now().time_since_epoch().count()) / + NANOSECONDS_PER_SECOND; plot_juggler_value_msg->set_timestamp(now); for (auto const& [key, val] : values) { @@ -479,8 +479,8 @@ BangBangTrajectory1DAngular createAngularTrajectoryFromParams( robot_constants.robot_max_ang_acceleration_rad_per_s_2)); } -double convertDribblerModeToDribblerSpeed(TbotsProto::DribblerMode dribbler_mode, - RobotConstants_t robot_constants) +int convertDribblerModeToDribblerSpeed(TbotsProto::DribblerMode dribbler_mode, + RobotConstants_t robot_constants) { switch (dribbler_mode) { @@ -489,10 +489,10 @@ double convertDribblerModeToDribblerSpeed(TbotsProto::DribblerMode dribbler_mode case TbotsProto::DribblerMode::MAX_FORCE: return robot_constants.max_force_dribbler_speed_rpm; case TbotsProto::DribblerMode::OFF: - return 0.0; + return 0; default: LOG(WARNING) << "DribblerMode is invalid" << std::endl; - return 0.0; + return 0; } } diff --git a/src/proto/message_translation/tbots_protobuf.h b/src/proto/message_translation/tbots_protobuf.h index 15f8cef4ed..50ab53c374 100644 --- a/src/proto/message_translation/tbots_protobuf.h +++ b/src/proto/message_translation/tbots_protobuf.h @@ -267,8 +267,8 @@ BangBangTrajectory1DAngular createAngularTrajectoryFromParams( * * @return the dribbler speed in RPM */ -double convertDribblerModeToDribblerSpeed(TbotsProto::DribblerMode dribbler_mode, - RobotConstants_t robot_constants); +int convertDribblerModeToDribblerSpeed(TbotsProto::DribblerMode dribbler_mode, + RobotConstants_t robot_constants); /** * Convert max allowed speed mode to max allowed speed diff --git a/src/proto/message_translation/tbots_protobuf_test.cpp b/src/proto/message_translation/tbots_protobuf_test.cpp index d64cb0708d..9cdde04170 100644 --- a/src/proto/message_translation/tbots_protobuf_test.cpp +++ b/src/proto/message_translation/tbots_protobuf_test.cpp @@ -74,31 +74,34 @@ class TbotsProtobufTest : public ::testing::Test auto traj_path_nodes_1 = traj_path_1.getTrajectoryPathNodes(); auto traj_path_nodes_2 = traj_path_2.getTrajectoryPathNodes(); ASSERT_EQ(traj_path_nodes_1.size(), traj_path_nodes_2.size()); - ASSERT_FLOAT_EQ(traj_path_nodes_1[0].getTrajectoryEndTime(), - traj_path_nodes_2[0].getTrajectoryEndTime()); - for (int i = 0; i < traj_path_nodes_1.size(); i++) + // In some cases, the trajectory end time may have lost precision when converting + // between doubles and floats + ASSERT_NEAR(traj_path_nodes_1[0].getTrajectoryEndTime(), + traj_path_nodes_2[0].getTrajectoryEndTime(), 0.000001); + + for (std::size_t i = 0; i < traj_path_nodes_1.size(); i++) { EXPECT_EQ(traj_path_nodes_1[i].getTrajectory()->getPosition(0.0), traj_path_nodes_2[i].getTrajectory()->getPosition(0.0)) << " Position at index " << i << " is not equal"; } - for (int i = 0; i < traj_path_nodes_1.size(); i++) + for (std::size_t i = 0; i < traj_path_nodes_1.size(); i++) { EXPECT_EQ(traj_path_nodes_1[i].getTrajectory()->getVelocity(0.0), traj_path_nodes_2[i].getTrajectory()->getVelocity(0.0)) << " Velocity at index " << i << " is not equal"; } - for (int i = 0; i < traj_path_nodes_1.size(); i++) + for (std::size_t i = 0; i < traj_path_nodes_1.size(); i++) { EXPECT_EQ(traj_path_nodes_1[i].getTrajectory()->getAcceleration(0.0), traj_path_nodes_2[i].getTrajectory()->getAcceleration(0.0)) << " Acceleration at index " << i << " is not equal"; } - for (int i = 0; i < traj_path_nodes_1.size(); i++) + for (std::size_t i = 0; i < traj_path_nodes_1.size(); i++) { EXPECT_EQ(traj_path_nodes_1[i].getTrajectory()->getDestination(), traj_path_nodes_2[i].getTrajectory()->getDestination()) @@ -176,7 +179,7 @@ TEST_P(TrajectoryParamConversionTest, trajectory_params_msg_test) start_position, initial_destination, initial_velocity, constraints); TrajectoryPath trajectory_path(trajectory, BangBangTrajectory2D::generator); - for (int i = 1; i < sub_destinations.size(); i++) + for (std::size_t i = 1; i < sub_destinations.size(); i++) { trajectory_path.append(sub_destination_connection_times[i - 1], sub_destinations[i], constraints); @@ -195,12 +198,13 @@ TEST_P(TrajectoryParamConversionTest, trajectory_params_msg_test) *(params.mutable_initial_velocity()) = *createVectorProto(initial_velocity); params.set_max_speed_mode(max_allowed_speed_mode); - for (int i = 0; i < sub_destinations.size(); ++i) + for (std::size_t i = 0; i < sub_destinations.size(); ++i) { TbotsProto::TrajectoryPathParams2D::SubDestination sub_destination_proto; *(sub_destination_proto.mutable_sub_destination()) = *createPointProto(sub_destinations[i]); - sub_destination_proto.set_connection_time_s(sub_destination_connection_times[i]); + sub_destination_proto.set_connection_time_s( + static_cast(sub_destination_connection_times[i])); *(params.add_sub_destinations()) = sub_destination_proto; } diff --git a/src/proto/primitive/primitive_msg_factory.cpp b/src/proto/primitive/primitive_msg_factory.cpp index d1cd2ecc3f..5aef38a878 100644 --- a/src/proto/primitive/primitive_msg_factory.cpp +++ b/src/proto/primitive/primitive_msg_factory.cpp @@ -13,7 +13,7 @@ std::unique_ptr createStopPrimitiveProto() } std::unique_ptr createDirectControlPrimitive( - const Vector &velocity, AngularVelocity angular_velocity, double dribbler_speed_rpm, + const Vector &velocity, AngularVelocity angular_velocity, int dribbler_speed_rpm, const TbotsProto::AutoChipOrKick &auto_chip_or_kick) { auto direct_control_primitive_msg = std::make_unique(); @@ -30,7 +30,7 @@ std::unique_ptr createDirectControlPrimitive( direct_control_primitive_msg->mutable_direct_control() ->mutable_motor_control() - ->set_dribbler_speed_rpm(static_cast(dribbler_speed_rpm)); + ->set_dribbler_speed_rpm(dribbler_speed_rpm); *(direct_control_primitive_msg->mutable_direct_control() ->mutable_power_control() diff --git a/src/proto/primitive/primitive_msg_factory.h b/src/proto/primitive/primitive_msg_factory.h index 40378ebd18..403395b0c6 100644 --- a/src/proto/primitive/primitive_msg_factory.h +++ b/src/proto/primitive/primitive_msg_factory.h @@ -30,5 +30,5 @@ std::unique_ptr createStopPrimitiveProto(); * @return Pointer to the DirectControl Primitive */ std::unique_ptr createDirectControlPrimitive( - const Vector &velocity, AngularVelocity angular_velocity, double dribbler_rpm, + const Vector &velocity, AngularVelocity angular_velocity, int dribbler_rpm, const TbotsProto::AutoChipOrKick &auto_chip_or_kick); diff --git a/src/proto/ssl_gc_api.proto b/src/proto/ssl_gc_api.proto index 98e6db7288..1f2c3d04fc 100644 --- a/src/proto/ssl_gc_api.proto +++ b/src/proto/ssl_gc_api.proto @@ -56,4 +56,6 @@ message Input optional bool reset_match = 2; // An updated config delta optional Config config_delta = 3; + // Continue with action + optional ContinueAction continue_action = 4; } diff --git a/src/proto/ssl_gc_change.proto b/src/proto/ssl_gc_change.proto index 2b99446f67..41762b1057 100644 --- a/src/proto/ssl_gc_change.proto +++ b/src/proto/ssl_gc_change.proto @@ -9,6 +9,7 @@ import "proto/ssl_gc_game_event.proto"; import "proto/ssl_gc_referee_message.proto"; import "google/protobuf/timestamp.proto"; +import "google/protobuf/wrappers.proto"; // A state change message StateChange @@ -35,183 +36,185 @@ message Change oneof change { - NewCommand new_command = 2; - ChangeStage change_stage = 3; - SetBallPlacementPos set_ball_placement_pos = 4; - AddYellowCard add_yellow_card = 5; - AddRedCard add_red_card = 6; - YellowCardOver yellow_card_over = 7; - AddGameEvent add_game_event = 8; - AddPassiveGameEvent add_passive_game_event = 19; - AddProposal add_proposal = 9; - StartBallPlacement start_ball_placement = 10; - Continue continue = 11; - UpdateConfig update_config = 12; - UpdateTeamState update_team_state = 13; - SwitchColors switch_colors = 14; - Revert revert = 15; - NewGameState new_game_state = 17; - AcceptProposalGroup accept_proposal_group = 18; + NewCommand new_command_change = 2; + ChangeStage change_stage_change = 3; + SetBallPlacementPos set_ball_placement_pos_change = 4; + AddYellowCard add_yellow_card_change = 5; + AddRedCard add_red_card_change = 6; + YellowCardOver yellow_card_over_change = 7; + AddGameEvent add_game_event_change = 8; + AddPassiveGameEvent add_passive_game_event_change = 19; + AddProposal add_proposal_change = 9; + UpdateConfig update_config_change = 12; + UpdateTeamState update_team_state_change = 13; + SwitchColors switch_colors_change = 14; + Revert revert_change = 15; + NewGameState new_game_state_change = 17; + AcceptProposalGroup accept_proposal_group_change = 18; + SetStatusMessage set_status_message_change = 20; } -} - -// New referee command -message NewCommand -{ - // The command - optional Command command = 1; -} -// Switch to a new stage -message ChangeStage -{ - // The new stage - optional Referee.Stage new_stage = 1; -} + // New referee command + message NewCommand + { + // The command + optional Command command = 1; + } -// Set the ball placement pos -message SetBallPlacementPos -{ - // The position in [m] - optional Vector2 pos = 1; -} + // Switch to a new stage + message ChangeStage + { + // The new stage + optional Referee.Stage new_stage = 1; + } -// Add a new yellow card -message AddYellowCard -{ - // The team that the card is for - optional Team for_team = 1; - // The game event that caused the card - optional GameEvent caused_by_game_event = 2; -} + // Set the ball placement pos + message SetBallPlacementPos + { + // The position in [m] + optional Vector2 pos = 1; + } -// Add a new red card -message AddRedCard -{ - // The team that the card is for - optional Team for_team = 1; - // The game event that caused the card - optional GameEvent caused_by_game_event = 2; -} + // Add a new yellow card + message AddYellowCard + { + // The team that the card is for + optional Team for_team = 1; + // The game event that caused the card + optional GameEvent caused_by_game_event = 2; + } -// Trigger when a yellow card timed out -message YellowCardOver -{ - // The team that the card was for - optional Team for_team = 1; -} + // Add a new red card + message AddRedCard + { + // The team that the card is for + optional Team for_team = 1; + // The game event that caused the card + optional GameEvent caused_by_game_event = 2; + } -// Add a new game event -message AddGameEvent -{ - // The game event - optional GameEvent game_event = 1; -} + // Trigger when a yellow card timed out + message YellowCardOver + { + // The team that the card was for + optional Team for_team = 1; + } -// Add a new passive game event (that is only logged, but does not automatically trigger -// anything) -message AddPassiveGameEvent -{ - // The game event - optional GameEvent game_event = 1; -} + // Add a new game event + message AddGameEvent + { + // The game event + optional GameEvent game_event = 1; + } -// Add a new proposal (i.e. from an auto referee for majority voting) -message AddProposal -{ - // The proposal - optional Proposal proposal = 1; -} + // Add a new passive game event (that is only logged, but does not automatically + // trigger anything) + message AddPassiveGameEvent + { + // The game event + optional GameEvent game_event = 1; + } -// Accept a proposal group (that contain one or more proposals of the same type) -message AcceptProposalGroup -{ - // The id of the group - optional uint32 group_id = 1; - // An identifier of the acceptor - optional string accepted_by = 2; -} + // Add a new proposal (i.e. from an auto referee for majority voting) + message AddProposal + { + // The proposal + optional Proposal proposal = 1; + } -// Initiate ball placement -message StartBallPlacement {} + // Accept a proposal group (that contain one or more proposals of the same type) + message AcceptProposalGroup + { + // The id of the group + optional string group_id = 3; + // An identifier of the acceptor + optional string accepted_by = 2; + } -// Continue with the next referee command -message Continue {} + // Update some configuration + message UpdateConfig + { + // The division to play with + optional Division division = 1; + // the team that does/did the first kick off + optional Team first_kickoff_team = 2; + reserved 3; // auto_continue moved to gcState + // The match type + optional MatchType match_type = 4; + // The number of robots per team + optional google.protobuf.Int32Value max_robots_per_team = 5; + } -// Update some configuration -message UpdateConfig -{ - // The division to play with - optional Division division = 1; - // the team that does/did the first kick off - optional Team first_kickoff_team = 2; - // Enable automatic continuation when all conditions are met - optional bool auto_continue = 3; - // The match type - optional MatchType match_type = 4; -} + // Update the current state of a team (all fields that should be updated are set) + message UpdateTeamState + { + // The team + optional Team for_team = 1; + + // Change the name of the team + optional google.protobuf.StringValue team_name = 2; + // Change the number of goals that the teams has at the moment + optional google.protobuf.Int32Value goals = 3; + // The id of the goal keeper + optional google.protobuf.Int32Value goalkeeper = 4; + // The number of timeouts that the team has left + optional google.protobuf.Int32Value timeouts_left = 5; + // The timeout time that the team has left + optional google.protobuf.StringValue timeout_time_left = 6; + // Does the team play on the positive or the negative half (in ssl-vision + // coordinates)? + optional google.protobuf.BoolValue on_positive_half = 7; + // The number of ball placement failures + optional google.protobuf.Int32Value ball_placement_failures = 8; + // Can the team place the ball, or is ball placement for this team disabled and + // should be skipped? + optional google.protobuf.BoolValue can_place_ball = 9; + // The number of challenge flags that the team has left + optional google.protobuf.Int32Value challenge_flags_left = 21; + // The number of bot substitutions left by the team in this halftime + optional google.protobuf.Int32Value bot_substitutions_left = 22; + // Does the team want to substitute a robot in the next possible situation? + optional google.protobuf.BoolValue requests_bot_substitution = 10; + // Does the team want to take a timeout in the next possible situation? + optional google.protobuf.BoolValue requests_timeout = 17; + // Does the team want to challenge a recent decision of the referee? + optional google.protobuf.BoolValue requests_challenge = 18; + // Does the team want to request an emergency stop? + optional google.protobuf.BoolValue requests_emergency_stop = 19; + // Update a certain yellow card of the team + optional YellowCard yellow_card = 20; + // Update a certain red card of the team + optional RedCard red_card = 12; + // Update a certain foul of the team + optional Foul foul = 13; + // Remove the yellow card with this id + optional google.protobuf.UInt32Value remove_yellow_card = 14; + // Remove the red card with this id + optional google.protobuf.UInt32Value remove_red_card = 15; + // Remove the foul with this id + optional google.protobuf.UInt32Value remove_foul = 16; + } -// Update the current state of a team (all fields that should be updated are set) -message UpdateTeamState -{ - // The team - optional Team for_team = 1; - - // Change the name of the team - optional string team_name = 2; - // Change the number of goals that the teams has at the moment - optional int32 goals = 3; - // The id of the goal keeper - optional int32 goalkeeper = 4; - // The number of timeouts that the team has left - optional int32 timeouts_left = 5; - // The timeout time that the team has left - optional string timeout_time_left = 6; - // Does the team play on the positive or the negative half (in ssl-vision - // coordinates)? - optional bool on_positive_half = 7; - // The number of ball placement failures - optional int32 ball_placement_failures = 8; - // Can the team place the ball, or is ball placement for this team disabled and should - // be skipped? - optional bool can_place_ball = 9; - // The number of challenge flags that the team has left - optional int32 challenge_flags_left = 21; - // Does the team want to substitute a robot in the next possible situation? - optional bool requests_bot_substitution = 10; - // Does the team want to take a timeout in the next possible situation? - optional bool requests_timeout = 17; - // Does the team want to challenge a recent decision of the referee? - optional bool requests_challenge = 18; - // Does the team want to request an emergency stop? - optional bool requests_emergency_stop = 19; - // Update a certain yellow card of the team - optional YellowCard yellow_card = 20; - // Update a certain red card of the team - optional RedCard red_card = 12; - // Update a certain foul of the team - optional Foul foul = 13; - // Remove the yellow card with this id - optional uint32 remove_yellow_card = 14; - // Remove the red card with this id - optional uint32 remove_red_card = 15; - // Remove the foul with this id - optional uint32 remove_foul = 16; -} + // Switch the team colors + message SwitchColors {} -// Switch the team colors -message SwitchColors {} + // Revert a certain change + message Revert + { + // The id of the change + optional int32 change_id = 1; + } -// Revert a certain change -message Revert -{ - // The id of the change - optional int32 change_id = 1; -} + // Change the current game state + message NewGameState + { + // The new game state + optional GameState game_state = 1; + } -// Change the current game state -message NewGameState -{ - // The new game state - optional GameState game_state = 1; + message SetStatusMessage + { + // The new status message + optional string status_message = 1; + } } diff --git a/src/proto/ssl_gc_engine.proto b/src/proto/ssl_gc_engine.proto index 1b6c271021..dce2f0bceb 100644 --- a/src/proto/ssl_gc_engine.proto +++ b/src/proto/ssl_gc_engine.proto @@ -5,26 +5,25 @@ package SSLProto; import "proto/ssl_gc_geometry.proto"; import "proto/ssl_gc_common.proto"; +import "google/protobuf/timestamp.proto"; + // The GC state contains settings and state independent of the match state message GcState { - // The state of each team + // the state of each team map team_state = 1; // the states of the auto referees map auto_ref_state = 2; - // the states of the attached trackers - map tracker_state = 3; - - // the state of the currently selected tracker - optional GcStateTracker tracker_state_gc = 4; + // the attached trackers (uuid -> source_name) + map trackers = 3; - // can the match be continued right now? - optional bool ready_to_continue = 5; + // the next actions that can be executed when continuing + repeated ContinueAction continue_actions = 4; - // list of issues that hinders the game from continuing - repeated string continuation_issues = 6; + // the next actions that can be executed when continuing + repeated ContinueHint continue_hints = 5; } // The GC state for a single team @@ -104,3 +103,61 @@ message Robot // robot position [m] optional Vector2 pos = 2; } + +message ContinueAction +{ + // type of action that will be performed next + required Type type = 1; + + // for which team (if team specific) + required Team for_team = 2; + + // list of issues that hinders the game from continuing + repeated string continuation_issues = 3; + + // timestamp at which the action will be ready (to give some preparation time) + optional google.protobuf.Timestamp ready_at = 4; + + // state of the action + optional State state = 5; + + enum Type + { + TYPE_UNKNOWN = 0; + HALT = 1; + RESUME_FROM_HALT = 10; + STOP_GAME = 2; + FORCE_START = 11; + FREE_KICK = 17; + NEXT_COMMAND = 3; + BALL_PLACEMENT_START = 4; + BALL_PLACEMENT_CANCEL = 9; + BALL_PLACEMENT_COMPLETE = 14; + BALL_PLACEMENT_FAIL = 15; + TIMEOUT_START = 5; + TIMEOUT_STOP = 6; + BOT_SUBSTITUTION = 7; + NEXT_STAGE = 8; + END_GAME = 16; + ACCEPT_GOAL = 12; + REJECT_GOAL = 20; + NORMAL_START = 13; + CHALLENGE_ACCEPT = 18; + CHALLENGE_REJECT = 19; + } + + enum State + { + STATE_UNKNOWN = 0; + BLOCKED = 1; + WAITING = 2; + READY_AUTO = 3; + READY_MANUAL = 4; + DISABLED = 5; + } +} + +message ContinueHint +{ + required string message = 1; +} diff --git a/src/proto/ssl_gc_engine_config.proto b/src/proto/ssl_gc_engine_config.proto index 6a71aafdbd..5c0ef9231e 100644 --- a/src/proto/ssl_gc_engine_config.proto +++ b/src/proto/ssl_gc_engine_config.proto @@ -17,6 +17,9 @@ message Config // The list of available teams repeated string teams = 4; + // Enable or disable auto continuation + optional bool auto_continue = 5; + // Behaviors for each game event enum Behavior { diff --git a/src/proto/ssl_gc_game_event.proto b/src/proto/ssl_gc_game_event.proto index bf510a37b7..7f103ed443 100644 --- a/src/proto/ssl_gc_game_event.proto +++ b/src/proto/ssl_gc_game_event.proto @@ -15,6 +15,10 @@ import "proto/ssl_gc_geometry.proto"; // so. message GameEvent { + // A globally unique id of the game event. + optional string id = 50; + + // The type of the game event. optional Type type = 40; // The origins of this game event. @@ -23,6 +27,9 @@ message GameEvent // Ignored if sent by autoRef to game controller. repeated string origin = 41; + // Unix timestamp in microseconds when the event was created. + optional uint64 created_timestamp = 49; + // the event that occurred oneof event { @@ -43,6 +50,7 @@ message GameEvent BotPushedBot bot_pushed_bot = 24; BotHeldBallDeliberately bot_held_ball_deliberately = 26; BotTippedOver bot_tipped_over = 27; + BotDroppedParts bot_dropped_parts = 51; // Non-Stopping Fouls @@ -69,17 +77,45 @@ message GameEvent PlacementSucceeded placement_succeeded = 5; PenaltyKickFailed penalty_kick_failed = 45; - NoProgressInGame no_progress_in_game = 2; - PlacementFailed placement_failed = 3; - MultipleCards multiple_cards = 32; - MultipleFouls multiple_fouls = 34; - BotSubstitution bot_substitution = 37; - TooManyRobots too_many_robots = 38; - ChallengeFlag challenge_flag = 46; - EmergencyStop emergency_stop = 47; + NoProgressInGame no_progress_in_game = 2; + PlacementFailed placement_failed = 3; + MultipleCards multiple_cards = 32; + MultipleFouls multiple_fouls = 34; + BotSubstitution bot_substitution = 37; + ExcessiveBotSubstitution excessive_bot_substitution = 52; + TooManyRobots too_many_robots = 38; + ChallengeFlag challenge_flag = 46; + ChallengeFlagHandled challenge_flag_handled = 48; + EmergencyStop emergency_stop = 47; UnsportingBehaviorMinor unsporting_behavior_minor = 35; UnsportingBehaviorMajor unsporting_behavior_major = 36; + + // Deprecated events + + // replaced by ready_to_continue flag + Prepared prepared = 1 [deprecated = true]; + // obsolete + IndirectGoal indirect_goal = 9 [deprecated = true]; + // replaced by the meta-information in the possible_goal event + ChippedGoal chipped_goal = 10 [deprecated = true]; + // obsolete + KickTimeout kick_timeout = 12 [deprecated = true]; + // rule removed + AttackerTouchedOpponentInDefenseArea attacker_touched_opponent_in_defense_area = + 16 [deprecated = true]; + // obsolete + AttackerTouchedOpponentInDefenseArea + attacker_touched_opponent_in_defense_area_skipped = 42 [deprecated = true]; + // obsolete + BotCrashUnique bot_crash_unique_skipped = 23 [deprecated = true]; + // can not be used as long as autoRefs do not judge pushing + BotPushedBot bot_pushed_bot_skipped = 25 [deprecated = true]; + // rule removed + DefenderInDefenseAreaPartially defender_in_defense_area_partially = 30 + [deprecated = true]; + // the referee msg already indicates this + MultiplePlacementFailures multiple_placement_failures = 33 [deprecated = true]; } // the ball left the field normally @@ -89,7 +125,7 @@ message GameEvent required Team by_team = 1; // the bot that last touched the ball optional uint32 by_bot = 2; - // the location where the ball left the field + // the location where the ball left the field [m] optional Vector2 location = 3; } // the ball left the field via goal line and a team committed an aimless kick @@ -99,9 +135,9 @@ message GameEvent required Team by_team = 1; // the bot that last touched the ball optional uint32 by_bot = 2; - // the location where the ball left the field + // the location where the ball left the field [m] optional Vector2 location = 3; - // the location where the ball was last touched + // the location where the ball was last touched [m] optional Vector2 kick_location = 4; } // a team shot a goal @@ -113,12 +149,13 @@ message GameEvent optional Team kicking_team = 6; // the bot that shot the goal optional uint32 kicking_bot = 2; - // the location where the ball entered the goal + // the location where the ball entered the goal [m] optional Vector2 location = 3; // the location where the ball was kicked (for deciding if this was a valid goal) + // [m] optional Vector2 kick_location = 4; // the maximum height the ball reached during the goal kick (for deciding if this - // was a valid goal) + // was a valid goal) [m] optional float max_ball_height = 5; // number of robots of scoring team when the ball entered the goal (for deciding // if this was a valid goal) @@ -135,9 +172,9 @@ message GameEvent required Team by_team = 1; // the bot that kicked the ball - at least the team must be set optional uint32 by_bot = 2; - // the location where the ball entered the goal + // the location where the ball entered the goal [m] optional Vector2 location = 3; - // the location where the ball was kicked + // the location where the ball was kicked [m] optional Vector2 kick_location = 4; } // the ball entered the goal, but was initially chipped @@ -147,12 +184,12 @@ message GameEvent required Team by_team = 1; // the bot that kicked the ball optional uint32 by_bot = 2; - // the location where the ball entered the goal + // the location where the ball entered the goal [m] optional Vector2 location = 3; - // the location where the ball was kicked + // the location where the ball was kicked [m] optional Vector2 kick_location = 4; // the maximum height [m] of the ball, before it entered the goal and since the - // last kick + // last kick [m] optional float max_ball_height = 5; } // a bot moved too fast while the game was stopped @@ -162,7 +199,7 @@ message GameEvent required Team by_team = 1; // the bot that was too fast optional uint32 by_bot = 2; - // the location of the bot + // the location of the bot [m] optional Vector2 location = 3; // the bot speed [m/s] optional float speed = 4; @@ -174,7 +211,7 @@ message GameEvent required Team by_team = 1; // the bot that violates the distance to the kick point optional uint32 by_bot = 2; - // the location of the bot + // the location of the bot [m] optional Vector2 location = 3; // the distance [m] from bot to the kick point (including the minimum radius) optional float distance = 4; @@ -186,7 +223,7 @@ message GameEvent optional uint32 bot_yellow = 1; // the bot of the blue team optional uint32 bot_blue = 2; - // the location of the crash (center between both bots) + // the location of the crash (center between both bots) [m] optional Vector2 location = 3; // the calculated crash speed [m/s] of the two bots optional float crash_speed = 4; @@ -207,7 +244,7 @@ message GameEvent optional uint32 violator = 2; // the bot of the opposite team that was involved in the crash optional uint32 victim = 3; - // the location of the crash (center between both bots) + // the location of the crash (center between both bots) [m] optional Vector2 location = 4; // the calculated crash speed vector [m/s] of the two bots optional float crash_speed = 5; @@ -227,7 +264,7 @@ message GameEvent optional uint32 violator = 2; // the bot of the opposite team that was pushed optional uint32 victim = 3; - // the location of the push (center between both bots) + // the location of the push (center between both bots) [m] optional Vector2 location = 4; // the pushed distance [m] optional float pushed_distance = 5; @@ -239,9 +276,21 @@ message GameEvent required Team by_team = 1; // the bot that tipped over optional uint32 by_bot = 2; - // the location of the bot + // the location of the bot [m] optional Vector2 location = 3; - // the location of the ball at the moment when this foul occurred + // the location of the ball at the moment when this foul occurred [m] + optional Vector2 ball_location = 4; + } + // a bot dropped parts + message BotDroppedParts + { + // the team that found guilty + required Team by_team = 1; + // the bot that dropped the parts + optional uint32 by_bot = 2; + // the location where the parts were dropped [m] + optional Vector2 location = 3; + // the location of the ball at the moment when this foul occurred [m] optional Vector2 ball_location = 4; } // a defender other than the keeper was fully located inside its own defense and @@ -252,7 +301,7 @@ message GameEvent required Team by_team = 1; // the bot that is inside the penalty area optional uint32 by_bot = 2; - // the location of the bot + // the location of the bot [m] optional Vector2 location = 3; // the distance [m] from bot case to the nearest point outside the defense area optional float distance = 4; @@ -269,7 +318,7 @@ message GameEvent optional Vector2 location = 3; // the distance [m] that the bot is inside the penalty area optional float distance = 4; - // the location of the ball at the moment when this foul occurred + // the location of the ball at the moment when this foul occurred [m] optional Vector2 ball_location = 5; } // an attacker touched the ball inside the opponent defense area @@ -279,7 +328,7 @@ message GameEvent required Team by_team = 1; // the bot that is inside the penalty area optional uint32 by_bot = 2; - // the location of the bot + // the location of the bot [m] optional Vector2 location = 3; // the distance [m] that the bot is inside the penalty area optional float distance = 4; @@ -291,7 +340,7 @@ message GameEvent required Team by_team = 1; // the bot that kicked too fast optional uint32 by_bot = 2; - // the location of the ball at the time of the highest speed + // the location of the ball at the time of the highest speed [m] optional Vector2 location = 3; // the absolute initial ball speed (kick speed) [m/s] optional float initial_ball_speed = 4; @@ -305,9 +354,9 @@ message GameEvent required Team by_team = 1; // the bot that dribbled too far optional uint32 by_bot = 2; - // the location where the dribbling started + // the location where the dribbling started [m] optional Vector2 start = 3; - // the location where the maximum dribbling distance was reached + // the location where the maximum dribbling distance was reached [m] optional Vector2 end = 4; } // an attacker touched the opponent robot inside defense area @@ -319,7 +368,7 @@ message GameEvent optional uint32 by_bot = 2; // the bot of the opposite team that was touched optional uint32 victim = 4; - // the location of the contact point between both bots + // the location of the contact point between both bots [m] optional Vector2 location = 3; } // an attacker touched the ball multiple times when it was not allowed to @@ -329,7 +378,7 @@ message GameEvent required Team by_team = 1; // the bot that touched the ball twice optional uint32 by_bot = 2; - // the location of the ball when it was first touched + // the location of the ball when it was first touched [m] optional Vector2 location = 3; } // an attacker was located too near to the opponent defense area during stop or free @@ -340,11 +389,11 @@ message GameEvent required Team by_team = 1; // the bot that is too close to the defense area optional uint32 by_bot = 2; - // the location of the bot + // the location of the bot [m] optional Vector2 location = 3; // the distance [m] of the bot to the penalty area optional float distance = 4; - // the location of the ball at the moment when this foul occurred + // the location of the ball at the moment when this foul occurred [m] optional Vector2 ball_location = 5; } // a bot held the ball for too long @@ -354,7 +403,7 @@ message GameEvent required Team by_team = 1; // the bot that holds the ball optional uint32 by_bot = 2; - // the location of the ball + // the location of the ball [m] optional Vector2 location = 3; // the duration [s] that the bot hold the ball optional float duration = 4; @@ -366,10 +415,10 @@ message GameEvent required Team by_team = 1; // the bot that interfered the placement optional uint32 by_bot = 2; - // the location of the bot + // the location of the bot [m] optional Vector2 location = 3; } - // a team collected multiple cards (yellow and red), which results in a penalty kick + // a team collected multiple yellow cards message MultipleCards { // the team that received multiple yellow cards @@ -380,6 +429,8 @@ message GameEvent { // the team that collected multiple fouls required Team by_team = 1; + // the list of game events that caused the multiple fouls + repeated GameEvent caused_game_events = 2; } // a team failed to place the ball multiple times in a row message MultiplePlacementFailures @@ -392,7 +443,7 @@ message GameEvent { // the team that that should have kicked required Team by_team = 1; - // the location of the ball + // the location of the ball [m] optional Vector2 location = 2; // the time [s] that was waited optional float time = 3; @@ -412,6 +463,8 @@ message GameEvent required Team by_team = 1; // the remaining distance [m] from ball to placement position optional float remaining_distance = 2; + // the distance [m] of the nearest own robot to the ball + optional float nearest_own_bot_distance = 3; } // a team was found guilty for minor unsporting behavior message UnsportingBehaviorMinor @@ -434,7 +487,7 @@ message GameEvent { // the team that found guilty required Team by_team = 1; - // the location of the ball + // the location of the ball [m] optional Vector2 location = 2; // the duration [s] that the keeper hold the ball optional float duration = 3; @@ -464,12 +517,26 @@ message GameEvent // the team that substitutes robots required Team by_team = 1; } + // A foul for excessive bot substitutions + message ExcessiveBotSubstitution + { + // the team that substitutes robots + required Team by_team = 1; + } // A challenge flag, requested by a team previously, is flagged message ChallengeFlag { - // the team that substitutes robots + // the team that requested the challenge flag required Team by_team = 1; } + // A challenge, flagged recently, has been handled by the referee + message ChallengeFlagHandled + { + // the team that requested the challenge flag + required Team by_team = 1; + // the challenge was accepted by the referee + required bool accepted = 2; + } // An emergency stop, requested by team previously, occurred message EmergencyStop { @@ -485,7 +552,7 @@ message GameEvent optional int32 num_robots_allowed = 2; // number of robots currently on the field optional int32 num_robots_on_field = 3; - // the location of the ball at the moment when this foul occurred + // the location of the ball at the moment when this foul occurred [m] optional Vector2 ball_location = 4; } // a robot chipped the ball over the field boundary out of the playing surface @@ -493,7 +560,7 @@ message GameEvent { // the team that has too many robots required Team by_team = 1; - // the location of the ball + // the location of the ball [m] optional Vector2 location = 2; } // the penalty kick failed (by time or by keeper) @@ -501,8 +568,10 @@ message GameEvent { // the team that last touched the ball required Team by_team = 1; - // the location of the ball at the moment of this event + // the location of the ball at the moment of this event [m] optional Vector2 location = 2; + // an explanation of the failure + optional string reason = 3; } enum Type @@ -526,6 +595,7 @@ message GameEvent BOT_PUSHED_BOT = 24; // triggered by human ref BOT_HELD_BALL_DELIBERATELY = 26; // triggered by human ref BOT_TIPPED_OVER = 27; // triggered by human ref + BOT_DROPPED_PARTS = 47; // triggered by human ref // Non-Stopping Fouls @@ -539,6 +609,7 @@ message GameEvent DEFENDER_TOO_CLOSE_TO_KICK_POINT = 29; // triggered by autoRef BOT_TOO_FAST_IN_STOP = 28; // triggered by autoRef BOT_INTERFERED_PLACEMENT = 20; // triggered by autoRef + EXCESSIVE_BOT_SUBSTITUTION = 48; // triggered by GC // Scoring goals @@ -552,16 +623,30 @@ message GameEvent PLACEMENT_SUCCEEDED = 5; // triggered by autoRef PENALTY_KICK_FAILED = 43; // triggered by GC and autoRef - NO_PROGRESS_IN_GAME = 2; // triggered by GC - PLACEMENT_FAILED = 3; // triggered by GC - MULTIPLE_CARDS = 32; // triggered by GC - MULTIPLE_FOULS = 34; // triggered by GC - BOT_SUBSTITUTION = 37; // triggered by GC - TOO_MANY_ROBOTS = 38; // triggered by GC - CHALLENGE_FLAG = 44; // triggered by GC - EMERGENCY_STOP = 45; // triggered by GC + NO_PROGRESS_IN_GAME = 2; // triggered by GC + PLACEMENT_FAILED = 3; // triggered by GC + MULTIPLE_CARDS = 32; // triggered by GC + MULTIPLE_FOULS = 34; // triggered by GC + BOT_SUBSTITUTION = 37; // triggered by GC + TOO_MANY_ROBOTS = 38; // triggered by GC + CHALLENGE_FLAG = 44; // triggered by GC + CHALLENGE_FLAG_HANDLED = 46; // triggered by GC + EMERGENCY_STOP = 45; // triggered by GC UNSPORTING_BEHAVIOR_MINOR = 35; // triggered by human ref UNSPORTING_BEHAVIOR_MAJOR = 36; // triggered by human ref + + // Deprecated events + + PREPARED = 1 [deprecated = true]; + INDIRECT_GOAL = 9 [deprecated = true]; + CHIPPED_GOAL = 10 [deprecated = true]; + KICK_TIMEOUT = 12 [deprecated = true]; + ATTACKER_TOUCHED_OPPONENT_IN_DEFENSE_AREA = 16 [deprecated = true]; + ATTACKER_TOUCHED_OPPONENT_IN_DEFENSE_AREA_SKIPPED = 40 [deprecated = true]; + BOT_CRASH_UNIQUE_SKIPPED = 23 [deprecated = true]; + BOT_PUSHED_BOT_SKIPPED = 25 [deprecated = true]; + DEFENDER_IN_DEFENSE_AREA_PARTIALLY = 30 [deprecated = true]; + MULTIPLE_PLACEMENT_FAILURES = 33 [deprecated = true]; } } diff --git a/src/proto/ssl_gc_referee_message.proto b/src/proto/ssl_gc_referee_message.proto index 0b5540a155..24006daddc 100644 --- a/src/proto/ssl_gc_referee_message.proto +++ b/src/proto/ssl_gc_referee_message.proto @@ -75,7 +75,7 @@ message Referee // // If the stage runs over its specified time, this value // becomes negative. - optional sint32 stage_time_left = 3; + optional sint64 stage_time_left = 3; // These are the "fine" states of play on the field. enum Command @@ -101,16 +101,20 @@ message Referee // The blue team may take a direct free kick. DIRECT_FREE_BLUE = 9; // The yellow team may take an indirect free kick. - INDIRECT_FREE_YELLOW = 10; + INDIRECT_FREE_YELLOW = 10 [deprecated = true]; // The blue team may take an indirect free kick. - INDIRECT_FREE_BLUE = 11; + INDIRECT_FREE_BLUE = 11 [deprecated = true]; // The yellow team is currently in a timeout. TIMEOUT_YELLOW = 12; // The blue team is currently in a timeout. TIMEOUT_BLUE = 13; // The yellow team just scored a goal. // For information only. - // For rules compliance, teams must treat as STOP. + // Deprecated: Use the score field from the team infos instead. That way, you can + // also detect revoked goals. + GOAL_YELLOW = 14 [deprecated = true]; + // The blue team just scored a goal. See also GOAL_YELLOW. + GOAL_BLUE = 15 [deprecated = true]; // Equivalent to STOP, but the yellow team must pick up the ball and // drop it in the Designated Position. BALL_PLACEMENT_YELLOW = 16; @@ -163,6 +167,12 @@ message Referee // Indicate if the team reached the maximum allowed ball placement failures and is // thus not allowed to place the ball anymore optional bool ball_placement_failures_reached = 15; + // The team is allowed to substitute one or more robots currently + optional bool bot_substitution_allowed = 16; + // The number of bot substitutions left by the team in this halftime + optional uint32 bot_substitutions_left = 17; + // The number of microseconds left for current bot substitution + optional uint32 bot_substitution_time_left = 18; } // Information about the two teams. @@ -185,6 +195,11 @@ message Referee // coordinate system. Obviously, the yellow team will play on the opposite half. optional bool blue_team_on_positive_half = 10; + // The game event that caused the referee command. + // deprecated in favor of game_events. + // optional Game_Event game_event = 11 [deprecated = true]; + reserved 11; + // The command that will be issued after the current stoppage and ball placement to // continue the game. optional Command next_command = 12; @@ -194,7 +209,7 @@ message Referee reserved 13; repeated GameEvent game_events = 16; - // All non-finished proposed game events that may be processed next. + // All proposed game events that were detected since the last RUNNING state. reserved 14; repeated GameEventProposalGroup game_event_proposals = 17; @@ -205,14 +220,19 @@ message Referee // * free kicks // * kickoff, penalty kick, force start // * ball placement - optional int32 current_action_time_remaining = 15; + optional int64 current_action_time_remaining = 15; + + // A message that can be displayed to the spectators, like a reason for a stoppage. + optional string status_message = 20; } // List of matching proposals message GameEventProposalGroup { - // The proposed game event. - repeated GameEvent game_event = 1; + // Unique ID of this group + optional string id = 3; + // The proposed game events + repeated GameEvent game_events = 1; // Whether the proposal group was accepted optional bool accepted = 2; } diff --git a/src/proto/ssl_gc_state.proto b/src/proto/ssl_gc_state.proto index 4cb9443aff..4ae750ff07 100644 --- a/src/proto/ssl_gc_state.proto +++ b/src/proto/ssl_gc_state.proto @@ -33,17 +33,17 @@ message Foul message Command { required Type type = 1; - optional Team for_team = 2; + required Team for_team = 2; enum Type { - UNKNOWN = 0; - HALT = 1; - STOP = 2; - NORMAL_START = 3; - FORCE_START = 4; - DIRECT = 5; - INDIRECT = 6; + UNKNOWN = 0; + HALT = 1; + STOP = 2; + NORMAL_START = 3; + FORCE_START = 4; + DIRECT = 5; + reserved 6; // INDIRECT KICKOFF = 7; PENALTY = 8; TIMEOUT = 9; @@ -80,10 +80,13 @@ message Proposal message ProposalGroup { - // List of proposals in this group + // Unique ID of this group + optional string id = 4; + // The proposals in this group repeated Proposal proposals = 1; // Whether the proposal group was accepted optional bool accepted = 2; + reserved 3; // uint32 id } message TeamInfo @@ -105,6 +108,9 @@ message TeamInfo optional google.protobuf.Timestamp requests_timeout_since = 15; optional google.protobuf.Timestamp requests_emergency_stop_since = 16; optional int32 challenge_flags = 17; + optional bool bot_substitution_allowed = 18; + optional int32 bot_substitutions_left = 19; + optional google.protobuf.Duration bot_substitution_time_left = 20; } message State @@ -122,7 +128,18 @@ message State repeated GameEvent game_events = 13; repeated ProposalGroup proposal_groups = 14; optional Division division = 15; - optional bool auto_continue = 16; - optional Team first_kickoff_team = 17; - optional MatchType match_type = 18; + reserved 16; + optional Team first_kickoff_team = 17; + optional MatchType match_type = 18; + optional google.protobuf.Timestamp ready_continue_time = 20; + optional ShootoutState shootout_state = 21; + optional string status_message = 22; + // The maximum number of bots per team (overwrites the division config) + optional int32 max_bots_per_team = 23; +} + +message ShootoutState +{ + optional Team next_team = 1; + map number_of_attempts = 2; } diff --git a/src/shared/2021_robot_constants.cpp b/src/shared/2021_robot_constants.cpp index 303afdde6c..f2900737a4 100644 --- a/src/shared/2021_robot_constants.cpp +++ b/src/shared/2021_robot_constants.cpp @@ -17,8 +17,8 @@ RobotConstants_t create2021RobotConstants(void) .front_of_robot_width_meters = 0.11f, .dribbler_width_meters = 0.07825f, // Dribbler speeds are negative as that is the direction that sucks the ball in - .indefinite_dribbler_speed_rpm = -10000.0f, - .max_force_dribbler_speed_rpm = -12000.0f, + .indefinite_dribbler_speed_rpm = -10000, + .max_force_dribbler_speed_rpm = -12000, // Motor constant .motor_max_acceleration_m_per_s_2 = 4.5f, diff --git a/src/shared/robot_constants.h b/src/shared/robot_constants.h index d8f283eb9b..af9bbee29e 100644 --- a/src/shared/robot_constants.h +++ b/src/shared/robot_constants.h @@ -67,11 +67,11 @@ typedef struct RobotConstants float dribbler_width_meters; // Indefinite dribbler mode sets a speed that can be maintained indefinitely [rpm] - float indefinite_dribbler_speed_rpm; + int indefinite_dribbler_speed_rpm; // Max force dribbler mode sets the speed that applies the maximum amount of force on // the ball [rpm] - float max_force_dribbler_speed_rpm; + int max_force_dribbler_speed_rpm; // The maximum acceleration achievable by our motors [m/s^2] float motor_max_acceleration_m_per_s_2; diff --git a/src/software/autoref/run_autoref.sh b/src/software/autoref/run_autoref.sh index 75f21be914..a4f3c8a61b 100755 --- a/src/software/autoref/run_autoref.sh +++ b/src/software/autoref/run_autoref.sh @@ -3,7 +3,7 @@ # Runs the Tigers Autoref binary that is set up by "setup_software.sh". By default, wrapper runs the autoreferee in headless, active mode. If an additional argument is passed in to the script, it is forwarded to the binary. cd "/opt/tbotspython/autoReferee/" -export JAVA_HOME="/usr/lib/jvm/jdk-17" +export JAVA_HOME="/opt/tbotspython/bin/jdk" bin/autoReferee -a $@ diff --git a/src/software/embedded/BUILD b/src/software/embedded/BUILD index cd35497c38..d43be47e00 100644 --- a/src/software/embedded/BUILD +++ b/src/software/embedded/BUILD @@ -90,6 +90,10 @@ cc_binary( "-lpthread", "-lrt", ], + target_compatible_with = [ + "@platforms//cpu:aarch64", + "@platforms//os:linux", + ], deps = [ ":thunderloop", "@boost//:program_options", diff --git a/src/software/embedded/ansible/requirements_lock.txt b/src/software/embedded/ansible/requirements_lock.txt index c846b976dd..0b23d0b1c0 100644 --- a/src/software/embedded/ansible/requirements_lock.txt +++ b/src/software/embedded/ansible/requirements_lock.txt @@ -1,5 +1,5 @@ # -# This file is autogenerated by pip-compile with Python 3.10 +# This file is autogenerated by pip-compile with Python 3.12 # by the following command: # # bazel run //software/embedded/ansible:requirements.update diff --git a/src/software/embedded/thunderloop.cpp b/src/software/embedded/thunderloop.cpp index 337a1f153d..6e7ec7cf76 100644 --- a/src/software/embedded/thunderloop.cpp +++ b/src/software/embedded/thunderloop.cpp @@ -136,7 +136,7 @@ Thunderloop::~Thunderloop() {} /* * Run the main robot loop! */ -[[noreturn]] void Thunderloop::runLoop() +void Thunderloop::runLoop() { // Timing struct timespec next_shot; diff --git a/src/software/embedded/thunderloop.h b/src/software/embedded/thunderloop.h index e8ffe23a3e..33fadb2577 100644 --- a/src/software/embedded/thunderloop.h +++ b/src/software/embedded/thunderloop.h @@ -55,7 +55,7 @@ class Thunderloop ~Thunderloop(); - void runLoop(); + [[noreturn]] void runLoop(); // Services std::unique_ptr motor_service_; diff --git a/src/software/estop/arduino_util.cpp b/src/software/estop/arduino_util.cpp index 0a3a6bb651..3ee6220e7e 100644 --- a/src/software/estop/arduino_util.cpp +++ b/src/software/estop/arduino_util.cpp @@ -6,6 +6,7 @@ #include #include +#include #include #include "shared/constants.h" @@ -109,7 +110,7 @@ std::vector ArduinoUtil::getSerialDevices() std::optional ArduinoUtil::readFileLine(boost::filesystem::path path) { - boost::filesystem::ifstream f(path.c_str()); + std::ifstream f(path.c_str()); std::string res; if (f.is_open()) { diff --git a/src/software/simulated_tests/requirements_lock.txt b/src/software/simulated_tests/requirements_lock.txt index 4fe396d6b2..8bf6d03071 100644 --- a/src/software/simulated_tests/requirements_lock.txt +++ b/src/software/simulated_tests/requirements_lock.txt @@ -1,5 +1,5 @@ # -# This file is autogenerated by pip-compile with Python 3.10 +# This file is autogenerated by pip-compile with Python 3.12 # by the following command: # # bazel run //software/simulated_tests:requirements.update diff --git a/src/software/thunderscope/BUILD b/src/software/thunderscope/BUILD index e188c0d202..1af288edc5 100644 --- a/src/software/thunderscope/BUILD +++ b/src/software/thunderscope/BUILD @@ -142,6 +142,9 @@ py_library( py_library( name = "constants", srcs = ["constants.py"], + deps = [ + requirement("protobuf"), + ], ) py_library( diff --git a/src/software/thunderscope/binary_context_managers/game_controller.py b/src/software/thunderscope/binary_context_managers/game_controller.py index a59463ac9e..5a2f4f3185 100644 --- a/src/software/thunderscope/binary_context_managers/game_controller.py +++ b/src/software/thunderscope/binary_context_managers/game_controller.py @@ -207,18 +207,18 @@ def send_gc_command( ci_input = CiInput(timestamp=int(time.time_ns())) api_input = Input() change = Change() - new_command = NewCommand() + new_command = Change.NewCommand() command = Command(type=gc_command, for_team=team) new_command.command.CopyFrom(command) - change.new_command.CopyFrom(new_command) + change.new_command_change.CopyFrom(new_command) api_input.change.CopyFrom(change) ci_input.api_inputs.append(api_input) # Do this only if ball placement pos is specified if final_ball_placement_point: # Set position - ball_placement_pos = SetBallPlacementPos() + ball_placement_pos = Change.SetBallPlacementPos() ball_placement_pos.pos.CopyFrom( Vector2( x=float(final_ball_placement_point.x()), @@ -227,16 +227,16 @@ def send_gc_command( ) change = Change() api_input = Input() - change.set_ball_placement_pos.CopyFrom(ball_placement_pos) + change.set_ball_placement_pos_change.CopyFrom(ball_placement_pos) api_input.change.CopyFrom(change) ci_input.api_inputs.append(api_input) # Start Placement - change = Change() api_input = Input() - start_placement = StartBallPlacement() - change.start_ball_placement.CopyFrom(start_placement) - api_input.change.CopyFrom(change) + start_placement = ContinueAction() + start_placement.type = ContinueAction.Type.BALL_PLACEMENT_START + start_placement.for_team = team + api_input.continue_action.CopyFrom(start_placement) ci_input.api_inputs.append(api_input) ci_output_list = self.send_ci_input(ci_input) @@ -264,7 +264,7 @@ def send_ci_input(self, ci_input: proto.ssl_gc_ci_pb2.CiInput) -> list[CiOutput] return ci_output_list - def reset_team(self, name: str, team: str) -> UpdateTeamState: + def reset_team(self, name: str, team: str) -> Change.UpdateTeamState: """Returns an UpdateTeamState proto for the gamecontroller to reset team info. :param name name of the new team @@ -272,27 +272,28 @@ def reset_team(self, name: str, team: str) -> UpdateTeamState: :return: corresponding UpdateTeamState proto """ - update_team_state = UpdateTeamState() + update_team_state = Change.UpdateTeamState() update_team_state.for_team = team - update_team_state.team_name = name - update_team_state.goals = 0 - update_team_state.timeouts_left = 4 - update_team_state.timeout_time_left = "05:00" - update_team_state.can_place_ball = True + update_team_state.team_name.value = name + update_team_state.goals.value = 0 + update_team_state.timeouts_left.value = 4 + update_team_state.timeout_time_left.value = "05:00" + update_team_state.can_place_ball.value = True return update_team_state - def reset_game(self, division: proto.ssl_gc_common_pb2.Division) -> UpdateConfig: + def reset_game( + self, division: proto.ssl_gc_common_pb2.Division + ) -> Change.UpdateConfig: """Returns an UpdateConfig proto for the Gamecontroller to reset game info. :param division the Division proto corresponding to the game division to set up the Gamecontroller for :return: corresponding UpdateConfig proto """ - game_update = UpdateConfig() + game_update = Change.UpdateConfig() game_update.division = division game_update.first_kickoff_team = SslTeam.BLUE - game_update.auto_continue = True game_update.match_type = MatchType.FRIENDLY return game_update @@ -309,19 +310,21 @@ def reset_team_info( ci_input = CiInput(timestamp=int(time.time_ns())) input_blue_update = Input() input_blue_update.reset_match = True - input_blue_update.change.update_team_state.CopyFrom( + input_blue_update.change.update_team_state_change.CopyFrom( self.reset_team("BLUE", SslTeam.BLUE) ) input_yellow_update = Input() input_yellow_update.reset_match = True - input_yellow_update.change.update_team_state.CopyFrom( + input_yellow_update.change.update_team_state_change.CopyFrom( self.reset_team("YELLOW", SslTeam.YELLOW) ) input_game_update = Input() input_game_update.reset_match = True - input_game_update.change.update_config.CopyFrom(self.reset_game(division)) + input_game_update.change.update_config_change.CopyFrom( + self.reset_game(division) + ) ci_input.api_inputs.append(input_blue_update) ci_input.api_inputs.append(input_yellow_update) diff --git a/src/software/thunderscope/binary_context_managers/tigers_autoref.py b/src/software/thunderscope/binary_context_managers/tigers_autoref.py index cff5276956..efaae73314 100644 --- a/src/software/thunderscope/binary_context_managers/tigers_autoref.py +++ b/src/software/thunderscope/binary_context_managers/tigers_autoref.py @@ -101,14 +101,15 @@ def _force_gamecontroller_to_accept_all_events(self) -> list[CiOutput]: :return: a list of CiOutput protos from the Gamecontroller """ - game_event_proto_map = Config() + gc_engine_config = Config() + gc_engine_config.auto_continue = True for game_event in GameEvent.Type.DESCRIPTOR.values_by_name: - game_event_proto_map.game_event_behavior[game_event] = ( + gc_engine_config.game_event_behavior[game_event] = ( Config.Behavior.BEHAVIOR_ACCEPT ) - return self.gamecontroller.update_game_engine_config(game_event_proto_map) + return self.gamecontroller.update_game_engine_config(gc_engine_config) def _send_geometry(self) -> None: """Sends updated field geometry to the AutoRef so that the TigersAutoref knows about field sizes.""" diff --git a/src/software/thunderscope/log/g3log_widget.py b/src/software/thunderscope/log/g3log_widget.py index 62e3bd9941..447d7acb39 100644 --- a/src/software/thunderscope/log/g3log_widget.py +++ b/src/software/thunderscope/log/g3log_widget.py @@ -1,6 +1,5 @@ from pyqtgraph.Qt.QtWidgets import * import queue -import qdarktheme from software.py_constants import * import pyqtgraph.console as pg_console from proto.robot_log_msg_pb2 import RobotLog, LogLevel @@ -20,8 +19,6 @@ def __init__(self, buffer_size: int = 10): """ QWidget.__init__(self) - palette = qdarktheme.load_palette() - self.console_widget = pg_console.ConsoleWidget() self.console_widget.setStyleSheet( """ diff --git a/src/software/thunderscope/play/refereeinfo_widget.py b/src/software/thunderscope/play/refereeinfo_widget.py index 59b56448c7..c2fdf2211b 100644 --- a/src/software/thunderscope/play/refereeinfo_widget.py +++ b/src/software/thunderscope/play/refereeinfo_widget.py @@ -47,9 +47,13 @@ def refresh(self) -> None: if not referee_msg_dict: return + stage_time_left_s = ( + int(referee_msg_dict["stageTimeLeft"]) * SECONDS_PER_MICROSECOND + ) p = ( f"Packet Timestamp: {round(float(referee_msg_dict['packetTimestamp']) * SECONDS_PER_MICROSECOND, 3)}\n" - + f"Stage Time Left: {int(referee_msg_dict['stageTimeLeft'] * SECONDS_PER_MICROSECOND / SECONDS_PER_MINUTE)}:{int(referee_msg_dict['stageTimeLeft'] * SECONDS_PER_MICROSECOND % SECONDS_PER_MINUTE)}\n" + + f"Stage Time Left: {int(stage_time_left_s / SECONDS_PER_MINUTE):02d}" + + f":{int(stage_time_left_s % SECONDS_PER_MINUTE):02d}\n" + f"Stage: {referee_msg_dict['stage']}\n" + "Command: " + referee_msg_dict["command"] diff --git a/src/software/thunderscope/requirements.in b/src/software/thunderscope/requirements.in index 56d48cb1a0..6b87152786 100644 --- a/src/software/thunderscope/requirements.in +++ b/src/software/thunderscope/requirements.in @@ -1,3 +1,3 @@ -numpy==1.25.0 +numpy==1.26.4 +protobuf==5.27.3 pyqtgraph==0.13.7 -pyqtdarktheme==2.1.0 diff --git a/src/software/thunderscope/requirements_lock.txt b/src/software/thunderscope/requirements_lock.txt index cac8531f7d..90bfb381c3 100644 --- a/src/software/thunderscope/requirements_lock.txt +++ b/src/software/thunderscope/requirements_lock.txt @@ -1,45 +1,61 @@ # -# This file is autogenerated by pip-compile with Python 3.10 +# This file is autogenerated by pip-compile with Python 3.12 # by the following command: # # bazel run //software/thunderscope:requirements.update # -darkdetect==0.7.1 \ - --hash=sha256:3efe69f8ecd5f1b7f4fbb0d1d93f656b0e493c45cc49222380ffe2a529cbc866 \ - --hash=sha256:47be3cf5134432ddb616bbffc927237718407914993c82809983e7ccebf49013 - # via pyqtdarktheme -numpy==1.25.0 \ - --hash=sha256:0ac6edfb35d2a99aaf102b509c8e9319c499ebd4978df4971b94419a116d0790 \ - --hash=sha256:26815c6c8498dc49d81faa76d61078c4f9f0859ce7817919021b9eba72b425e3 \ - --hash=sha256:4aedd08f15d3045a4e9c648f1e04daca2ab1044256959f1f95aafeeb3d794c16 \ - --hash=sha256:4c69fe5f05eea336b7a740e114dec995e2f927003c30702d896892403df6dbf0 \ - --hash=sha256:5177310ac2e63d6603f659fadc1e7bab33dd5a8db4e0596df34214eeab0fee3b \ - --hash=sha256:5aa48bebfb41f93043a796128854b84407d4df730d3fb6e5dc36402f5cd594c0 \ - --hash=sha256:5b1b90860bf7d8a8c313b372d4f27343a54f415b20fb69dd601b7efe1029c91e \ - --hash=sha256:6c284907e37f5e04d2412950960894b143a648dea3f79290757eb878b91acbd1 \ - --hash=sha256:6d183b5c58513f74225c376643234c369468e02947b47942eacbb23c1671f25d \ - --hash=sha256:7412125b4f18aeddca2ecd7219ea2d2708f697943e6f624be41aa5f8a9852cc4 \ - --hash=sha256:7cd981ccc0afe49b9883f14761bb57c964df71124dcd155b0cba2b591f0d64b9 \ - --hash=sha256:85cdae87d8c136fd4da4dad1e48064d700f63e923d5af6c8c782ac0df8044542 \ - --hash=sha256:8aa130c3042052d656751df5e81f6d61edff3e289b5994edcf77f54118a8d9f4 \ - --hash=sha256:95367ccd88c07af21b379be1725b5322362bb83679d36691f124a16357390153 \ - --hash=sha256:9c7211d7920b97aeca7b3773a6783492b5b93baba39e7c36054f6e749fc7490c \ - --hash=sha256:9e3f2b96e3b63c978bc29daaa3700c028fe3f049ea3031b58aa33fe2a5809d24 \ - --hash=sha256:b76aa836a952059d70a2788a2d98cb2a533ccd46222558b6970348939e55fc24 \ - --hash=sha256:b792164e539d99d93e4e5e09ae10f8cbe5466de7d759fc155e075237e0c274e4 \ - --hash=sha256:c0dc071017bc00abb7d7201bac06fa80333c6314477b3d10b52b58fa6a6e38f6 \ - --hash=sha256:cc3fda2b36482891db1060f00f881c77f9423eead4c3579629940a3e12095fe8 \ - --hash=sha256:d6b267f349a99d3908b56645eebf340cb58f01bd1e773b4eea1a905b3f0e4208 \ - --hash=sha256:d76a84998c51b8b68b40448ddd02bd1081bb33abcdc28beee6cd284fe11036c6 \ - --hash=sha256:e559c6afbca484072a98a51b6fa466aae785cfe89b69e8b856c3191bc8872a82 \ - --hash=sha256:ecc68f11404930e9c7ecfc937aa423e1e50158317bf67ca91736a9864eae0232 \ - --hash=sha256:f1accae9a28dc3cda46a91de86acf69de0d1b5f4edd44a9b0c3ceb8036dfff19 +numpy==1.26.4 \ + --hash=sha256:03a8c78d01d9781b28a6989f6fa1bb2c4f2d51201cf99d3dd875df6fbd96b23b \ + --hash=sha256:08beddf13648eb95f8d867350f6a018a4be2e5ad54c8d8caed89ebca558b2818 \ + --hash=sha256:1af303d6b2210eb850fcf03064d364652b7120803a0b872f5211f5234b399f20 \ + --hash=sha256:1dda2e7b4ec9dd512f84935c5f126c8bd8b9f2fc001e9f54af255e8c5f16b0e0 \ + --hash=sha256:2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010 \ + --hash=sha256:2e4ee3380d6de9c9ec04745830fd9e2eccb3e6cf790d39d7b98ffd19b0dd754a \ + --hash=sha256:3373d5d70a5fe74a2c1bb6d2cfd9609ecf686d47a2d7b1d37a8f3b6bf6003aea \ + --hash=sha256:47711010ad8555514b434df65f7d7b076bb8261df1ca9bb78f53d3b2db02e95c \ + --hash=sha256:4c66707fabe114439db9068ee468c26bbdf909cac0fb58686a42a24de1760c71 \ + --hash=sha256:50193e430acfc1346175fcbdaa28ffec49947a06918b7b92130744e81e640110 \ + --hash=sha256:52b8b60467cd7dd1e9ed082188b4e6bb35aa5cdd01777621a1658910745b90be \ + --hash=sha256:60dedbb91afcbfdc9bc0b1f3f402804070deed7392c23eb7a7f07fa857868e8a \ + --hash=sha256:62b8e4b1e28009ef2846b4c7852046736bab361f7aeadeb6a5b89ebec3c7055a \ + --hash=sha256:666dbfb6ec68962c033a450943ded891bed2d54e6755e35e5835d63f4f6931d5 \ + --hash=sha256:675d61ffbfa78604709862923189bad94014bef562cc35cf61d3a07bba02a7ed \ + --hash=sha256:679b0076f67ecc0138fd2ede3a8fd196dddc2ad3254069bcb9faf9a79b1cebcd \ + --hash=sha256:7349ab0fa0c429c82442a27a9673fc802ffdb7c7775fad780226cb234965e53c \ + --hash=sha256:7ab55401287bfec946ced39700c053796e7cc0e3acbef09993a9ad2adba6ca6e \ + --hash=sha256:7e50d0a0cc3189f9cb0aeb3a6a6af18c16f59f004b866cd2be1c14b36134a4a0 \ + --hash=sha256:95a7476c59002f2f6c590b9b7b998306fba6a5aa646b1e22ddfeaf8f78c3a29c \ + --hash=sha256:96ff0b2ad353d8f990b63294c8986f1ec3cb19d749234014f4e7eb0112ceba5a \ + --hash=sha256:9fad7dcb1aac3c7f0584a5a8133e3a43eeb2fe127f47e3632d43d677c66c102b \ + --hash=sha256:9ff0f4f29c51e2803569d7a51c2304de5554655a60c5d776e35b4a41413830d0 \ + --hash=sha256:a354325ee03388678242a4d7ebcd08b5c727033fcff3b2f536aea978e15ee9e6 \ + --hash=sha256:a4abb4f9001ad2858e7ac189089c42178fcce737e4169dc61321660f1a96c7d2 \ + --hash=sha256:ab47dbe5cc8210f55aa58e4805fe224dac469cde56b9f731a4c098b91917159a \ + --hash=sha256:afedb719a9dcfc7eaf2287b839d8198e06dcd4cb5d276a3df279231138e83d30 \ + --hash=sha256:b3ce300f3644fb06443ee2222c2201dd3a89ea6040541412b8fa189341847218 \ + --hash=sha256:b97fe8060236edf3662adfc2c633f56a08ae30560c56310562cb4f95500022d5 \ + --hash=sha256:bfe25acf8b437eb2a8b2d49d443800a5f18508cd811fea3181723922a8a82b07 \ + --hash=sha256:cd25bcecc4974d09257ffcd1f098ee778f7834c3ad767fe5db785be9a4aa9cb2 \ + --hash=sha256:d209d8969599b27ad20994c8e41936ee0964e6da07478d6c35016bc386b66ad4 \ + --hash=sha256:d5241e0a80d808d70546c697135da2c613f30e28251ff8307eb72ba696945764 \ + --hash=sha256:edd8b5fe47dab091176d21bb6de568acdd906d1887a4584a15a9a96a1dca06ef \ + --hash=sha256:f870204a840a60da0b12273ef34f7051e98c3b5961b61b0c2c1be6dfd64fbcd3 \ + --hash=sha256:ffa75af20b44f8dba823498024771d5ac50620e6915abac414251bd971b4529f # via # -r software/thunderscope/requirements.in # pyqtgraph -pyqtdarktheme==2.1.0 \ - --hash=sha256:5f8274ddfa3a5481ed9743cdb0f9debfeb7ff695b3a0d202a8104361d17dadb8 \ - --hash=sha256:8739d99502230fbaca42551ea033c9ae31c81c4ebfec2f1ffde38f32a18bea7a +protobuf==5.27.3 \ + --hash=sha256:043853dcb55cc262bf2e116215ad43fa0859caab79bb0b2d31b708f128ece035 \ + --hash=sha256:16ddf3f8c6c41e1e803da7abea17b1793a97ef079a912e42351eabb19b2cffe7 \ + --hash=sha256:68248c60d53f6168f565a8c76dc58ba4fa2ade31c2d1ebdae6d80f969cdc2d4f \ + --hash=sha256:82460903e640f2b7e34ee81a947fdaad89de796d324bcbc38ff5430bcdead82c \ + --hash=sha256:8572c6533e544ebf6899c360e91d6bcbbee2549251643d32c52cf8a5de295ba5 \ + --hash=sha256:a55c48f2a2092d8e213bd143474df33a6ae751b781dd1d1f4d953c128a415b25 \ + --hash=sha256:af7c0b7cfbbb649ad26132e53faa348580f844d9ca46fd3ec7ca48a1ea5db8a1 \ + --hash=sha256:b8a994fb3d1c11156e7d1e427186662b64694a62b55936b2b9348f0a7c6625ce \ + --hash=sha256:c2a105c24f08b1e53d6c7ffe69cb09d0031512f0b72f812dd4005b8112dbe91e \ + --hash=sha256:c84eee2c71ed83704f1afbf1a85c3171eab0fd1ade3b399b3fad0884cbcca8bf \ + --hash=sha256:dcb307cd4ef8fec0cf52cb9105a03d06fbb5275ce6d84a6ae33bc6cf84e0a07b # via -r software/thunderscope/requirements.in pyqtgraph==0.13.7 \ --hash=sha256:64f84f1935c6996d0e09b1ee66fe478a7771e3ca6f3aaa05f00f6e068321d9e3 \ diff --git a/src/software/thunderscope/thunderscope_config.py b/src/software/thunderscope/thunderscope_config.py index defc65d16d..f7d893b5ef 100644 --- a/src/software/thunderscope/thunderscope_config.py +++ b/src/software/thunderscope/thunderscope_config.py @@ -11,9 +11,9 @@ WidgetStretchData, ) import pyqtgraph +from qt_material import apply_stylesheet import signal import os -import qdarktheme @dataclass @@ -39,7 +39,11 @@ def initialize_application() -> None: app = pyqtgraph.mkQApp("Thunderscope") # Setup stylesheet - qdarktheme.setup_theme() + extra = { + # Make thunderscope more dense + "density_scale": "-2", + } + apply_stylesheet(app, theme="dark_blue.xml", extra=extra) def configure_robot_view_fullsystem( diff --git a/src/software/thunderscope/thunderscope_main.py b/src/software/thunderscope/thunderscope_main.py index 78b70a4e32..8645d6ce8d 100644 --- a/src/software/thunderscope/thunderscope_main.py +++ b/src/software/thunderscope/thunderscope_main.py @@ -4,6 +4,17 @@ import os import sys import threading + +import google.protobuf +from google.protobuf.internal import api_implementation + +protobuf_impl_type = api_implementation.Type() +assert protobuf_impl_type == "upb", ( + f"Trying to use the {protobuf_impl_type} protobuf implementation. " + "Please use the upb implementation, available in python protobuf version 4.21.0 and above." + f"The current version of protobuf is {google.protobuf.__version__}" +) + from software.thunderscope.thunderscope import Thunderscope from software.thunderscope.binary_context_managers import * from proto.import_all_protos import * diff --git a/src/software/util/make_enum/make_enum.hpp b/src/software/util/make_enum/make_enum.hpp index 7cba24dda9..39cb6eb431 100644 --- a/src/software/util/make_enum/make_enum.hpp +++ b/src/software/util/make_enum/make_enum.hpp @@ -1,5 +1,7 @@ #pragma once +#include + #include "software/util/make_enum/make_enum_helpers.hpp" /** diff --git a/src/software/util/make_enum/make_enum_helpers.hpp b/src/software/util/make_enum/make_enum_helpers.hpp index a80ca85f2e..ad0c679993 100644 --- a/src/software/util/make_enum/make_enum_helpers.hpp +++ b/src/software/util/make_enum/make_enum_helpers.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include diff --git a/src/tbots.py b/src/tbots.py index 9fe80434aa..874ce21ff9 100755 --- a/src/tbots.py +++ b/src/tbots.py @@ -167,7 +167,7 @@ # Used for when flashing Jetsons if args.flash_robots: - command += ["--cpu=jetson_nano"] + command += ["--platforms=//cc_toolchain:robot"] # Select debug binaries to run if args.select_debug_binaries: