Skip to content
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -155,3 +155,7 @@ src/.clangd

# external is a special directory for bazel so it should be ignored
src/external

# macOS folder info
.DS_Store

13 changes: 13 additions & 0 deletions environment_setup/macos_requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
ansible-lint==24.12.2
pyqtgraph==0.13.7
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A lot of these can be removed pending #3542 I think

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will do a merge test.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uhh I think bazel has no problem with your PR, everything compiles. But PyQt6 conflicts still exist with the current commit 9fce33a1727218c76ee0e1b37ee26bbbd1d0a1e1. I would guess this issue is normal because you have not resolved this PyQt lib conflict in your branch yet?

Full Error message:

INFO: Running command line: bazel-bin/software/thunderscope/thunderscope_main
  ⚠ Conflicting symlinks found when attempting to create venv. More than one package provides the file at these paths
   ╭─[1:208]
 1 │ /private/var/tmp/_bazel_liminghao/32d7fe8baee71625f01e1bffab4e0a4a/execroot/_main/bazel-out/darwin_arm64-fastbuild/bin/software/thunderscope/thunderscope_main.runfiles/.thunderscope_main.venv/lib/python3.12/site-packages/PyQt6/__init__.py
   ·                                                                                                                                                                                                                ───────────────┬───────────────
   ·                                                                                                                                                                                                                               ╰── Existing file in virtual environment
 2 │ /private/var/tmp/_bazel_liminghao/32d7fe8baee71625f01e1bffab4e0a4a/execroot/_main/bazel-out/darwin_arm64-fastbuild/bin/software/thunderscope/thunderscope_main.runfiles/rules_python++pip+thunderscope_deps_312_pyqt6/site-packages/PyQt6/__init__.py
   ·                                                                                                                                                                                                                       ───────────────┬───────────────
   ·                                                                                                                                                                                                                                      ╰── Next file to link
   ╰────
  help: Set `package_collisions = "ignore"` on the binary or test rule to ignore this warning

Traceback (most recent call last):
  File "/private/var/tmp/_bazel_liminghao/32d7fe8baee71625f01e1bffab4e0a4a/execroot/_main/bazel-out/darwin_arm64-fastbuild/bin/software/thunderscope/thunderscope_main.runfiles/_main/software/thunderscope/thunderscope_main.py", line 18, in <module>
    from software.thunderscope.thunderscope import Thunderscope
  File "/private/var/tmp/_bazel_liminghao/32d7fe8baee71625f01e1bffab4e0a4a/execroot/_main/bazel-out/darwin_arm64-fastbuild/bin/software/thunderscope/thunderscope_main.runfiles/_main/software/thunderscope/thunderscope.py", line 7, in <module>
    import pyqtgraph
  File "/private/var/tmp/_bazel_liminghao/32d7fe8baee71625f01e1bffab4e0a4a/execroot/_main/bazel-out/darwin_arm64-fastbuild/bin/software/thunderscope/thunderscope_main.runfiles/.thunderscope_main.venv/lib/python3.12/site-packages/pyqtgraph/__init__.py", line 18, in <module>
    from .colors import palette
  File "/private/var/tmp/_bazel_liminghao/32d7fe8baee71625f01e1bffab4e0a4a/execroot/_main/bazel-out/darwin_arm64-fastbuild/bin/software/thunderscope/thunderscope_main.runfiles/.thunderscope_main.venv/lib/python3.12/site-packages/pyqtgraph/colors/palette.py", line 1, in <module>
    from ..Qt import QtGui
  File "/private/var/tmp/_bazel_liminghao/32d7fe8baee71625f01e1bffab4e0a4a/execroot/_main/bazel-out/darwin_arm64-fastbuild/bin/software/thunderscope/thunderscope_main.runfiles/.thunderscope_main.venv/lib/python3.12/site-packages/pyqtgraph/Qt/__init__.py", line 57, in <module>
    raise ImportError("PyQtGraph requires one of PyQt5, PyQt6, PySide2 or PySide6; none of these packages could be imported.")
ImportError: PyQtGraph requires one of PyQt5, PyQt6, PySide2 or PySide6; none of these packages could be imported.

thefuzz==0.19.0
iterfzf==0.5.0.20.0
python-Levenshtein==0.25.1
psutil==5.9.0
PyOpenGL==3.1.6
ruff==0.5.5
pyqt-toast-notification==1.3.2
grpcio-tools==1.71.0
platformio==6.1.18
pyqt6==6.9.1

1 change: 1 addition & 0 deletions environment_setup/setup_software.sh
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ print_status_msg "Done setting up cross compiler for robot software"

print_status_msg "Setting Up Python Development Headers"
install_python_dev_cross_compile_headers $g_arch
install_python_toolchain_headers
print_status_msg "Done Setting Up Python Development Headers"

print_status_msg "Setting Up PlatformIO"
Expand Down
102 changes: 102 additions & 0 deletions environment_setup/setup_software_mac.sh
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should make sure you're using the same c++ compuler version as Ubuntu (to minimize the number of c++ compatibility changes that are needed)

Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
#!/bin/bash
set -x
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# UBC Thunderbots macOS Software Setup
#
# This script will install all required libraries and dependencies to build
# and run the Thunderbots codebase on macOS, including the AI and unit tests.
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#

# Save the parent dir of this script
CURR_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd)
cd "$CURR_DIR" || exit

source util.sh

arch=$(uname -m)
print_status_msg "Detected architecture: ${arch}"

# Check for Homebrew and install if missing
if ! command -v brew &>/dev/null; then
print_status_msg "Installing Homebrew..."
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

# Configure Homebrew in current shell
if [ "$arch" = "arm64" ]; then
eval "$(/opt/homebrew/bin/brew shellenv)"
else
eval "$(/usr/local/bin/brew shellenv)"
fi
Comment thread
Lmh-java marked this conversation as resolved.
Outdated
fi

print_status_msg "Installing Utilities and Dependencies"

# Update Homebrew
brew update

# Install required packages
host_software_packages=(
cmake@4
python@3.12
bazelisk
openjdk@21
pyqt@6
qt@6
node@20
go@1.24
clang-format@20
Comment thread
nycrat marked this conversation as resolved.
)

for pkg in "${host_software_packages[@]}"; do
if ! brew list "$pkg" &>/dev/null; then
print_status_msg "Installing $pkg..."
brew install "$pkg"
else
print_status_msg "$pkg already installed, skipping..."
fi
done

# Set up cache
mkdir /tmp/tbots_download_cache

# Set up Python
print_status_msg "Setting Up Python Environment"

# Create virtual environment
sudo python3.12 -m venv /opt/tbotspython
chmod
source /opt/tbotspython/bin/activate

# Install Python dependencies
sudo pip install --upgrade pip
sudo pip install -r macos_requirements.txt

print_status_msg "Done Setting Up Python Environment"

print_status_msg "Fetching game controller"
install_gamecontroller_macos

print_status_msg "Setting up TIGERS AutoRef"
install_java_macos
install_autoref_macos
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"
print_status_msg "Finished setting up AutoRef"

print_status_msg "Setting up cross compiler for robot software"
install_cross_compiler_mac
print_status_msg "Done setting up cross compiler for robot software"

print_status_msg "Setting Up Python Development Headers"
install_python_toolchain_headers
print_status_msg "Done Setting Up Python Development Headers"

print_status_msg "Granting Permissions to /opt/tbotspython"
sudo chown -R $(id -u):$(id -g) /opt/tbotspython
print_status_msg "Done Granting Permissions to /opt/tbotspython"

print_status_msg "Done Environment Configuration"

Comment thread
Lmh-java marked this conversation as resolved.
print_status_msg "Software Setup Complete"
print_status_msg "Note: Some changes require a new terminal session to take effect"

48 changes: 48 additions & 0 deletions environment_setup/util.sh
Comment thread
nycrat marked this conversation as resolved.
Comment thread
nycrat marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,15 @@ install_autoref() {
rm -rf /tmp/tbots_download_cache/autoReferee.zip /tmp/tbots_download_cache/AutoReferee-${autoref_commit}
}

install_autoref_macos() {
autoref_version=1.5.5
curl -L https://github.com/TIGERs-Mannheim/AutoReferee/releases/download/${autoref_version}/autoReferee.zip -o /tmp/tbots_download_cache/autoReferee.zip
unzip -q -o -d /tmp/tbots_download_cache/ /tmp/tbots_download_cache/autoReferee.zip

sudo mv /tmp/tbots_download_cache/autoReferee /opt/tbotspython/
rm -rf /tmp/tbots_download_cache/autoReferee.zip
}

install_bazel() {
download=https://github.com/bazelbuild/bazelisk/releases/download/v1.26.0/bazelisk-linux-arm64

Expand Down Expand Up @@ -35,6 +44,16 @@ install_cross_compiler() {
rm /tmp/tbots_download_cache/$full_file_name
}

install_cross_compiler_mac() {
file_name=aarch64-tbots-linux-gnu-for-aarch64
full_file_name=$file_name.tar.xz
curl -L "https://raw.githubusercontent.com/UBC-Thunderbots/Software-External-Dependencies/refs/heads/main/toolchain/$full_file_name" \
-o /tmp/tbots_download_cache/$full_file_name
tar -xf /tmp/tbots_download_cache/$full_file_name -C /tmp/tbots_download_cache/
sudo mv /tmp/tbots_download_cache/aarch64-tbots-linux-gnu /opt/tbotspython
rm /tmp/tbots_download_cache/$full_file_name
}

install_gamecontroller () {
arch=arm64
if is_x86 $1; then
Expand All @@ -46,6 +65,19 @@ install_gamecontroller () {
sudo chmod +x /opt/tbotspython/gamecontroller
}

install_gamecontroller_macos () {
curl -L https://github.com/RoboCup-SSL/ssl-game-controller/archive/refs/tags/v3.17.0.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.17.0
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.17.0 /tmp/tbots_download_cache/go /tmp/tbots_download_cache/go.tar.gz /tmp/tbots_download_cache/ssl-game-controller.zip
}

install_java () {
java_home=""
java_download=https://download.oracle.com/java/21/latest/jdk-21_linux-aarch64_bin.tar.gz
Expand All @@ -58,6 +90,17 @@ install_java () {
rm /tmp/tbots_download_cache/jdk-21.tar.gz
}

install_java_macos () {
java_home=""
java_download=https://download.oracle.com/java/21/latest/jdk-21_macos-aarch64_bin.tar.gz
curl -L $java_download -o /tmp/tbots_download_cache/jdk-21.tar.gz
mkdir /tmp/tbots_download_cache/jdk
tar -xzf /tmp/tbots_download_cache/jdk-21.tar.gz -C /tmp/tbots_download_cache
sudo mv /tmp/tbots_download_cache/jdk-21*/Contents/Home /opt/tbotspython/bin/jdk
rm /tmp/tbots_download_cache/jdk-21.tar.gz
rm -rf /tmp/tbots_download_cache/jdk
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Java Installed already from brew, I don't think we need this

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need a specific version of Java for autoref (Java 21)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose you're using the autoref binary package, so you can probably ignore this

install_python_dev_cross_compile_headers() {
mkdir -p /opt/tbotspython/cross_compile_headers
wget -N https://www.python.org/ftp/python/3.12.0/Python-3.12.0.tar.xz -O /tmp/tbots_download_cache/python-3.12.0.tar.xz
Expand Down Expand Up @@ -90,6 +133,11 @@ install_python_dev_cross_compile_headers() {
rm -rf /tmp/tbots_download_cache/python-3.12.0.tar.xz
}

install_python_toolchain_headers() {
sudo mkdir -p /opt/tbotspython/py_headers/include/
sudo ln -sfn "$(python3.12-config --includes | awk '{for(i=1;i<=NF;++i) if ($i ~ /^-I/) print substr($i, 3)}' | head -n1)" /opt/tbotspython/py_headers/include/
}

is_x86() {
if [[ $1 == "x86_64" ]]; then
return 0
Expand Down
4 changes: 2 additions & 2 deletions src/.bazelrc
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@ common --enable_platform_specific_config
build --incompatible_remove_legacy_whole_archive=False

# Escalate Warnings to fail Compile for Thunderbots code
build --features=external_include_paths
build --per_file_copt=proto/.*,proto/message_translation/.*,proto/primitive/.*,software/.*,shared/.*,-external/.*@-Wall,-Wextra,-Wno-unused-parameter,-Wno-deprecated,-Werror,-Wno-deprecated-declarations
build:linux --features=external_include_paths
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally these flags would also work on macos

Copy link
Copy Markdown
Contributor Author

@Lmh-java Lmh-java Nov 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, ideally it should also work on macos, but because the macos clang compiler is stricter than linux and reports millions of new errors (converted from warnings). :(

build:linux --per_file_copt=proto/.*,proto/message_translation/.*,proto/primitive/.*,software/.*,shared/.*,-external/.*@-Wall,-Wextra,-Wno-unused-parameter,-Wno-deprecated,-Werror,-Wno-deprecated-declarations
# TODO: #3492
# build --per_file_copt=software/.*,shared/.*,-external/.*@-Wconversion

Expand Down
2 changes: 1 addition & 1 deletion src/MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ new_local_repository(
new_local_repository(
name = "py_cc_toolchain_host",
build_file = "@//extlibs:py_cc_toolchain.BUILD",
path = "/usr/include/python3.12/",
path = "/opt/tbotspython/py_headers/include/python3.12/",
)

new_local_repository(
Expand Down
4 changes: 2 additions & 2 deletions src/extlibs/er_force_sim/src/amun/simulator/simulator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -677,12 +677,12 @@ void Simulator::handleSimulatorSetupCommand(const std::unique_ptr<amun::Command>

if (realism.has_vision_delay())
{
m_visionDelay = std::max(0l, realism.vision_delay());
m_visionDelay = std::max<int64_t>(0l, realism.vision_delay());
}

if (realism.has_vision_processing_time())
{
m_visionProcessingTime = std::max(0l, realism.vision_processing_time());
m_visionProcessingTime = std::max<int64_t>(0l, realism.vision_processing_time());
}

if (realism.has_simulate_dribbling())
Expand Down
14 changes: 13 additions & 1 deletion src/software/logger/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ cc_library(
],
deps = [
"@g3log",
":compat_flags",
],
)

Expand All @@ -19,7 +20,10 @@ cc_library(
"custom_logging_levels.h",
"logger.h",
],
linkopts = ["-lstdc++fs"],
linkopts = select({
"@platforms//os:linux": ["-lstdc++fs"],
"//conditions:default": [],
}),
deps = [
":coloured_cout_sink",
":csv_sink",
Expand All @@ -28,6 +32,7 @@ cc_library(
":protobuf_sink",
"@g3log",
"@g3sinks",
":compat_flags",
],
)

Expand Down Expand Up @@ -104,6 +109,7 @@ cc_library(
],
deps = [
"@g3log",
":compat_flags",
],
)

Expand Down Expand Up @@ -187,5 +193,11 @@ cc_library(
"@base64",
"@boost//:filesystem",
"@zlib",
":compat_flags",
],
)

cc_library(
name = "compat_flags",
srcs = ["compat_flags.h"],
)
18 changes: 18 additions & 0 deletions src/software/logger/compat_flags.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#pragma once

#include <chrono>

#if defined(__APPLE__)
using Clock = std::chrono::system_clock;
#else
using Clock = std::chrono::_V2::system_clock;
#endif

#if __cplusplus > 201703L
#include <filesystem>
namespace fs = std::filesystem;
#else
#include <experimental/filesystem>
namespace fs = std::experimental::filesystem;
#endif

6 changes: 1 addition & 5 deletions src/software/logger/csv_sink.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
#include "software/logger/csv_sink.h"

#if __cplusplus > 201703L
#include <filesystem>
#else
#include <experimental/filesystem>
#endif
#include "compat_flags.h"

CSVSink::CSVSink(const std::string& log_directory) : log_directory(log_directory) {}

Expand Down
5 changes: 2 additions & 3 deletions src/software/logger/log_merger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ std::list<g3::LogMessage> LogMerger::log(g3::LogMessage &log)
{
std::string msg = log.message();

std::chrono::_V2::system_clock::time_point current_time =
Clock::time_point current_time =
std::chrono::system_clock::now();
// add passed time from testing
current_time += passed_time;
Expand All @@ -38,8 +38,7 @@ std::list<g3::LogMessage> LogMerger::log(g3::LogMessage &log)
}
}

std::list<g3::LogMessage> LogMerger::_getOldMessages(
std::chrono::_V2::system_clock::time_point current_time)
std::list<g3::LogMessage> LogMerger::_getOldMessages(Clock::time_point current_time)
{
std::list<g3::LogMessage> result;
while (message_list.size() > 0)
Expand Down
14 changes: 6 additions & 8 deletions src/software/logger/log_merger.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <list>
#include <string>
#include <unordered_map>
#include "compat_flags.h"


/**
Expand Down Expand Up @@ -41,11 +42,9 @@ class LogMerger
* Looks through the message list for expired messages, removes them from the list and
* map, and returns them as strings
*/
std::list<g3::LogMessage> _getOldMessages(
std::chrono::_V2::system_clock::time_point current_time);
std::list<g3::LogMessage> _getOldMessages(Clock::time_point current_time);

const std::chrono::_V2::system_clock::duration LOG_MERGE_DURATION =
std::chrono::seconds(2);
const Clock::duration LOG_MERGE_DURATION = std::chrono::seconds(2);

private:
/**
Expand All @@ -55,10 +54,10 @@ class LogMerger
{
g3::LogMessage log;
std::string msg;
std::chrono::_V2::system_clock::time_point timestamp;
Clock::time_point timestamp;

Message(g3::LogMessage &log, std::string msg,
std::chrono::_V2::system_clock::time_point timestamp)
Clock::time_point timestamp)
: log(log), msg(msg), timestamp(timestamp)
{
}
Expand All @@ -68,8 +67,7 @@ class LogMerger
repeat_map; // maps string messages to their number of repeats for fast access
std::list<Message> message_list; // used to keep track of time order for messages

std::chrono::_V2::system_clock::duration
passed_time; // for testing, time passed manually
Clock::duration passed_time; // for testing, time passed manually

bool enable_merging;
};
Loading