Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
84 changes: 84 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
name: CI

on:
push:
branches: [master]
pull_request:

# A second push to the same PR makes the first run's result irrelevant.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
build:
name: Build (nix)
runs-on: ubuntu-latest
steps:
# The protocol definitions are a submodule; without them CMake fails at
# configure time with the "run git submodule update" message.
- uses: actions/checkout@v4
with:
submodules: recursive

- uses: DeterminateSystems/nix-installer-action@main
- uses: DeterminateSystems/magic-nix-cache-action@main

# The dev shell pins eigen_5. Ubuntu ships 3.4.0 through at least 26.04
# LTS, which lacks Matrix::canonicalEulerAngles() -- so this cannot be an
# apt-based job without patching the source.
- name: Build all targets
run: |
nix develop --command bash -c '
cmake -B build .
make -C build -j"$(nproc)" vision_processor geometry_benchmark blob_benchmark
'

python:
name: Python (wrapper_backend)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: recursive

- uses: DeterminateSystems/nix-installer-action@main
- uses: DeterminateSystems/magic-nix-cache-action@main

# Importing wrapper_backend runs protoc against the submodule and
# generates wrapper_backend/proto/, which mypy needs on its path even
# though it excludes the generated files themselves.
- name: Lint and type check
run: |
nix develop --command bash -c '
uv sync --locked
uv run python -c "import wrapper_backend"
uv run ruff check wrapper_backend/
uv run ruff format --check wrapper_backend/
uv run mypy
'

frontend:
name: Frontend (wrapper-frontend)
runs-on: ubuntu-latest
defaults:
run:
working-directory: wrapper-frontend
steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
cache-dependency-path: wrapper-frontend/package-lock.json

- run: npm ci

- run: npm run lint

- run: npm run format:check

- run: npm run check

- run: npm run build
3 changes: 3 additions & 0 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
image: ubuntu:latest

variables:
GIT_SUBMODULE_STRATEGY: recursive

stages:
- build

Expand Down
4 changes: 4 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[submodule "proto"]
path = proto
url = https://github.com/RoboCup-SSL/ssl-protocol-defs.git
branch = main
29 changes: 25 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,30 @@ link_libraries("m" "stdc++" ${YAML_CPP_LIBRARIES} ${OpenCV_LIBS} PkgConfig::LIBA
include_directories(SYSTEM ${YAML_INCLUDE_DIRS} ${OpenCV_INCLUDE_DIRS} ${SPINNAKER_INCLUDE_DIRS} Eigen3::Eigen ${mvIMPACT_INCLUDE_DIRS})

include_directories(src)
file(GLOB PROTO_FILES proto/*.proto)

set(PROTOC_OUT_DIR "${CMAKE_SOURCE_DIR}/src/proto")
include_directories("${PROTOC_OUT_DIR}")

# league proto repository provides a generator function that fixes OUT_DIR limitations with protoc provided function
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/proto/cmake")
include(SSLProtocolDefs)
set(PROTO_FILES
vision/ssl_vision_detection.proto
vision/ssl_vision_geometry.proto
vision/ssl_vision_wrapper.proto

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Sorry for the merge conflicts, config missing :D

vision/ssl_vp_config.proto
gamecontroller/ssl_gc_common.proto
gamecontroller/ssl_gc_game_event.proto
gamecontroller/ssl_gc_geometry.proto
gamecontroller/ssl_gc_referee_message.proto
)
ssl_protocol_defs_generate_cpp(
OUT_DIR "${PROTOC_OUT_DIR}"
PROTOS ${PROTO_FILES}
SOURCES_VAR PROTO_SRCS
HEADERS_VAR PROTO_HDRS
)

file(GLOB CL_KERNELS RELATIVE "${CMAKE_SOURCE_DIR}" kernel/*.cl)
file(GLOB_RECURSE SRC src/*.cpp src/*.c)
list(REMOVE_ITEM SRC "${CMAKE_SOURCE_DIR}/src/main.cpp" "${CMAKE_SOURCE_DIR}/src/geometry_benchmark.cpp" "${CMAKE_SOURCE_DIR}/src/blob_benchmark.cpp")
Expand Down Expand Up @@ -95,10 +118,8 @@ if(NOT "${CL_KERNEL_ASM_OLD}" STREQUAL "${CL_KERNEL_ASM}")
message(STATUS "(Re-)Generated cl_kernels.S")
endif()

add_custom_target(AUTOGENERATE DEPENDS "src/cl_kernels.S")
add_custom_target(AUTOGENERATE DEPENDS "src/cl_kernels.S" ${PROTO_SRCS} ${PROTO_HDRS})
set_property(SOURCE "src/cl_kernels.S" APPEND PROPERTY OBJECT_DEPENDS ${CL_KERNEL_PATHS})
protobuf_generate(TARGET AUTOGENERATE LANGUAGE cpp PROTOC_OUT_DIR "${CMAKE_SOURCE_DIR}/src" PROTOS ${PROTO_FILES})
get_property(PROTO_SRCS TARGET AUTOGENERATE PROPERTY SOURCES)
list(APPEND SRC ${PROTO_SRCS} "src/cl_kernels.S")

add_executable(${PROJECT_NAME} ${SRC} "src/main.cpp")
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ A modular replacement for `geom_publisher.py` plus a browser UI:
- `wrapper_backend/` — async Python (uv-managed). Owns the field geometry, absorbs incoming calibrations, exposes the bus over WebSocket. Run with `./start_wrapper.sh` (defaults to `geometry-divB.yml`). See [`wrapper_backend/README.md`](wrapper_backend/README.md).
- `wrapper-frontend/` — Svelte 5 + TypeScript + Vite. Connects to the backend's WebSocket and renders the operator UI. Run with `cd wrapper-frontend && npm install && npm run dev`. See [`wrapper-frontend/README.md`](wrapper-frontend/README.md).


## Dependency installation and compilation

### Only geom_publisher.py cam_viewer.py (e.g. vision expert laptop)
Expand Down Expand Up @@ -58,6 +57,7 @@ Installation with PIP: `pip install protobuf pyyaml`

3. Compile vision_processor:

git submodule update --init --recursive
cmake -B build .
make -C build vision_processor

Expand Down
27 changes: 27 additions & 0 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

91 changes: 91 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
{
description = "SSL vision_processor build environment";

inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
};

outputs =
{ self, nixpkgs }:
let
inherit (nixpkgs) lib;
systems = [ "x86_64-linux" "aarch64-linux" ];
forAllSystems = lib.genAttrs systems;
in
{
devShells = forAllSystems (
system:
let
pkgs = nixpkgs.legacyPackages.${system};

# Only what python/*.py needs at the system level. wrapper_backend/ is
# uv-managed (see pyproject.toml) and brings its own venv.
python = pkgs.python3.withPackages (ps: [
ps.protobuf
ps.pyyaml
ps.opencv4 # python/cam_viewer.py
]);

# pocl is a CPU OpenCL runtime. It makes the build environment
# self-contained and testable without a GPU driver; a real GPU ICD on
# the host is picked up instead when OCL_ICD_VENDORS points at it.
openclRuntime = pkgs.pocl;
in
{
default = pkgs.mkShell {
nativeBuildInputs = with pkgs; [
cmake
pkg-config
protobuf # provides protoc for both C++ and Python codegen
];

buildInputs = with pkgs; [
# Deliberately the nixpkgs default (3.4.x), matching what every
# distro ships: Debian, Ubuntu through 26.04 LTS, and Fedora are
# all still on 3.4. Pinning eigen_5 here would let code compile
# that does not build for anyone packaging against a distro Eigen.
eigen

opencv # core imgproc imgcodecs videoio
yaml-cpp
# Must match the ffmpeg nixpkgs built opencv against, currently
# 8.1.2. The default `ffmpeg` is 9.x, which links fine but loads a
# second set of libav* sonames alongside the ones opencv's videoio
# pulls in -- two copies of ffmpeg's global state in one process.
ffmpeg_8 # libavformat libavcodec libavutil
protobuf

opencl-headers # CL/cl.h
opencl-clhpp # CL/opencl.hpp (CL_HPP_TARGET_OPENCL_VERSION=300)
ocl-icd # libOpenCL.so, the ICD loader
openclRuntime

python
uv # wrapper_backend/
];

# The ICD loader finds runtimes through this. Without it the loader
# reports zero platforms and vision_processor exits at startup.
OCL_ICD_VENDORS = "${openclRuntime}/etc/OpenCL/vendors";

# uv must not download its own interpreter inside the shell.
UV_PYTHON = python.interpreter;
UV_PYTHON_DOWNLOADS = "never";

shellHook = ''
echo "vision_processor dev shell"
echo " eigen ${pkgs.eigen.version}"
echo " opencv ${pkgs.opencv.version}"
echo " ffmpeg ${pkgs.ffmpeg_8.version}"
echo " protobuf ${pkgs.protobuf.version}"
echo
echo " cmake -B build . && make -C build -j vision_processor"
echo
echo "Camera SDKs (Spinnaker, mvIMPACT) are proprietary and not"
echo "packaged here; the OpenCV backend is available."
'';
};
}
);
};
}
1 change: 1 addition & 0 deletions proto
Submodule proto added at 02cbc8
28 changes: 0 additions & 28 deletions proto/ssl_gc_common.proto

This file was deleted.

Loading