First Order Robotics core software stack for RoboCup SSL, an international league where teams build autonomous robotic teams to play football competitively.
- Setup Utama
- Repository Guide
- Setup grSim
- Setup AutoReferee
- Setup SSL Vision for Real Testing
- Field Guide
- System Design
- Milestones
- Install
pixipackage manager withcurl -fsSL https://pixi.sh/install.sh | shor click here for Windows installation Pixi installation - Restart or create a new terminal
- With pixi: just run
pixi installin the base folder and you're all setup. - Note that this also installs all modules with
__init__.py(so you need to run it again when you add an__init__.py) - In order to go into the
pixivenv, runpixi shell. You can also run any of the tasks in thepixi.tomlwithout first being in a pixi shell. See Pixi Tasks. - Finally, run
pixi run precommit-install. This will ensure that linting is done before you commit.
Note on CLAUDE.md: it is a symlink to AGENTS.md, which is the single source of agent
context (AGENTS.md is the cross-vendor default; Claude Code reads CLAUDE.md). Edit
AGENTS.md — never the symlink. Linux, macOS and WSL check this out correctly with no setup.
On native Windows, git only materialises symlinks with Developer Mode or Administrator
privileges enabled; without them CLAUDE.md arrives as a 9-byte text file, fixable with
git config --global core.symlinks true && git checkout -- CLAUDE.md.
Note
- if you are using the run button and it is selecting the wrong env (robosim) you will need to manually change the interpreter in VS Code using
Ctrl + Shift + P->Select Interpreter. - if you want to perform a one-off run (ad-hoc) use
pixi run python -m path.to.your_file, where you replace the/with.and remove the trailing.py.
pixi run <task_name> is the generic way to run a task. Some of the main tasks you can run:
pixi run mainruns main.pypixi run precommit-installdownloads the precommit hook to ensure that your code is formatted correctly when you commit and push.pixi run lintruns the full suite of precommit checkers on all files (You need to run the precommit install task above first).pixi run testruns pytest over theutama_core/tests/folderpixi run replay [-n <file_name>] [-p]plays a legacy pickle replay (./replays/<file_name>.pkl) in the rSoccer viewer.- Use
-n/--replay-fileto give the file name without.pkl; if not provided, defaults to the newest.pkldirectly in./replays. - Use
-p/--play-by-playfor step-by-step playback. - Matches run today write columnar
.npzreplays into./replays/<run>/; open those in the dashboard (pixi run python dashboard_server.py) instead.
- Use
pixi run runslists the tournament runs in./replayswith their start time, git commit, match and stall counts and arguments.
Everything lives under utama_core/:
engine: the tactic-kernel infrastructure:Strategy,Tactic,TickContext,MatchLog, referee-override plumbingstrategy: the strategies (one module perbuild_*_kernel_strategyfactory, re-exported bykernel_strategy.py), seedocs/strategies.mdtactics: reusableTacticimplementations that strategies composeskills: lowest level of control for individual robotsshared: geometry and helpers shared by tactics and skillscustom_referee: the in-process referee (rules, state machine, restart positioning, profiles)motion_planning: control algorithms for movement and path planningteam_controller: interfacing with vision (including processing) and robotsrun: the main running loop (StrategyRunner)data_processing: processors of vision, robot_info and referee raw datadashboard: the browser dashboardglobal_utils: utility functions shared across all foldersentities: classes for field, robot, data entities etc.rsoccer_simulator: lightweight rSoccer simulator for testingreplay: replay writing/reading, clip rendering and replay analysistests: all testsconfig: configs for the robots (defaults, settings, physical and referee constants, etc.)
Scripts, run with pixi run python <path> from the repository root:
| Script | Purpose |
|---|---|
main.py |
Exhibition demo: one attacker plus keeper over grSim with the dashboard (pixi run main) |
tools/tournament/round_robin.py |
Round-robin of every kernel strategy at smoke-test length; writes replays/tournament_*/ |
tools/tournament/full_match_tournament.py |
Full-length round-robin among the competitive-tier strategies |
tools/tournament/tournament_lib.py |
Shared match-running code for the tournament scripts (not run directly) |
tools/elo.py / tools/plot_elo.py |
Elo ratings from tournament summary.json files, and their plots |
tools/debug_match.py |
One-off match runner for tactic debugging; --dump-ticks writes per-tick poses and commanded targets |
tools/repro_from_replay.py |
Reload a replay's field state at a timestamp into a fresh headless rsim match |
dashboard_server.py |
Standalone dashboard for browsing replays and tournaments |
examples/demo_*.py |
Demos: custom referee, referee GUIs, dribbler test, Exhibition Road, split-shape match |
start_test_env.sh |
Starts grSim, the GameController and AutoReferee together |
-
Use typing for all variables.
-
Document your code on the subfolder's
README.mdand wiki. -
Download and install
Black Formatterfor code formatting- For VScode, go to View > Command Palette and search
Open User Settings (JSON) - Find the
"[python]"field and add the following lines:
"[python]": { "editor.defaultFormatter": "ms-python.black-formatter", # add this "editor.formatOnSave": true, # and add this }
- For VScode, go to View > Command Palette and search
- Each feature should live within its own branch of the repository. Clear out stale branches.
- Ensure that you have run
pixi run precommit-installat least once. This ensures that the pre-commit steps are run on each commit to clean up your code. - If the precommit fails, click on
Open Git Logon the popup window to view the error. Often times, the failure is automatically fixed and you just need to commit the changes the precommit hook makes. - The popup window can often be quite cryptic when it fails. If you are getting a
bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)popup on commit, this is not the actual cause of the failure. However, Windows decides to show this warning, because it is first warning in the output. To silence this:
sudo apt-get update
sudo apt-get install -y locales
sudo locale-gen en_US.UTF-8
sudo update-locale LANG=en_US.UTF-8
source ~/.bashrcFor a PR to be accepted, it must:
- have a
releasetag assigned, eitherrelease:major,release:minor, orrelease:patch. - Pass all CI checks, both tests and linting.
- Not be branched from a stale version of main. Remember to update the PR:
git checkout main
git checkout <your_branch>
git merge main- have all Copilot comments reviewed (Not all must be addressed: Copilot makes mistakes too, so don't blindly accept!)
- have at least one tick from an assigned reviewer
- Go to grSim repo and follow the installation steps.
- Change the values in the configuration to what is highlighted below:
- To run, execute
./bin/grSimin the cloned repo.
- Make sure
grSimis setup properly and can be called through terminal. git clonefrom AutoReferee repo in a folder named/AutoRefereein root directory.- Change
DIV_Ain/AutoReferee/config/moduli/moduli.xmltoDIV_B.
<globalConfiguration>
<environment>ROBOCUP</environment>
<geometry>DIV_B</geometry>
</globalConfiguration>- Get the latest compiled game controller and rename it to
ssl-game-controller. Save it in/ssl-game-controllerdirectory.
Once grSim, the GameController and AutoReferee are all set up per the steps above, ./start_test_env.sh launches all three together and tears them down on Ctrl+C. It starts nothing from this repo — run your own strategy separately once they are up — and it reminds you to open the GameController's web UI at http://localhost:8081/#/match (that port is the GameController's own; this repo's dashboard is :8080). See the comment block at the top of the script for what each process is for and its known rough edges.
You only need this when you specifically want the official GameController/AutoReferee in the loop. For everyday work the in-process CustomReferee replaces both, needs no external process, and behaves identically across RSim, grSim and real modes.
- Connect to an external hotspot and ensure both the vision Linux laptop and your personal laptop are connected to the same network.
- Allow inbound UDP packets through the port you set. Run the following command with admin privileges:
New-NetFirewallRule -DisplayName "Allow Multicast UDP 10006" -Direction Inbound -Protocol UDP -LocalPort 10006 -Action Allow
- Type "%USERPROFILE%" into "Windows + R", then add a
.wslconfigfile. Ensure that the file type is set to WSLCONFIG.
[wsl2] networkingMode=mirrored
- Restart WSL using
wsl --shutdown, then check the connection using the following command:
sudo tcpdump -i eth1 -n host 224.5.23.2 and udp port 10006
If you see UDP packets, everything is working.
- All coordinates and velocities will be in meters or meters per second.
- All angular properties will be in radians or radians per second, normalised between [pi, -pi]. A heading of radian 0 indicates a robot facing towards the positive x-axis (ie left to right).
- Unless otherwise stated, the coordinate system is aligned such that blue robots are on the left and yellow are on the right.
- The center of the field is marked as (0, 0).
The system design diagram is attached here for reference. For more information on the design, see here.
- 2024 November 20 - First goal in grSim (featuring Ray casting)


