Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
9501164
♻️ Split the simulator into an engine, a view, a bridge and an app ov…
GabrielCosme Sep 25, 2026
b4e8104
🎨 Build the maze arena in the contest colors, with the checker on the…
GabrielCosme Sep 25, 2026
684bbf8
🎥 Trace the path in the video, tint the robot and add an onboard camera
GabrielCosme Sep 25, 2026
5c81608
✨ Run the firmware with braking in turns and the racing line
GabrielCosme Sep 25, 2026
7c09b8f
🔥 Drop the specs, the maze generator and third_party, and stop tracki…
GabrielCosme Sep 27, 2026
3bafc37
♻️ Cut what nothing uses from the simulator, and fix what the review …
GabrielCosme Sep 27, 2026
7d3318a
✅ Check the contest, and the gate with less work
GabrielCosme Sep 27, 2026
1333ec7
📝 Describe the simulator as it is
GabrielCosme Sep 27, 2026
09950bf
⬆️ Follow the firmware onto the merged low level review
GabrielCosme Sep 27, 2026
f01eede
⬆️ Follow the firmware's restart of a stopped converter
GabrielCosme Sep 27, 2026
ac488d7
⬆️ Follow the firmware onto the rewritten main
GabrielCosme Sep 27, 2026
bb92655
⬆️ Follow the firmware's answer to the review of the navigation
GabrielCosme Sep 27, 2026
7219ac2
⬆️ Follow the firmware's revert of the turn factor, with the baseline…
GabrielCosme Sep 27, 2026
3296291
⬆️ Follow the firmware's pricing of turns, with the baseline recorded…
GabrielCosme Sep 27, 2026
b1112f3
⬆️ Follow the firmware's answer to the second review, with the baseli…
GabrielCosme Sep 27, 2026
af6b056
⬆️ Follow the firmware's third review and motor limited braking, with…
GabrielCosme Sep 27, 2026
85c8345
⬆️ Follow the firmware's main, with the fourth review and the baselin…
GabrielCosme Sep 27, 2026
da2395b
🔧 Build every host preset with GCC 15
GabrielCosme Sep 28, 2026
4a5686b
✨ Let the gate require byte identical runs
GabrielCosme Sep 28, 2026
0da2e7f
✨ Give the host SPI a device slot keyed by bus and chip select
GabrielCosme Sep 28, 2026
2ce776f
✨ Model the LSM6DSV and AS5047U as SPI devices
GabrielCosme Sep 28, 2026
4da4dac
✨ Start the recording once every column source is ready
GabrielCosme Sep 28, 2026
eca6d13
✨ Run the firmware's own SPI chip proxies over the chip models
GabrielCosme Sep 28, 2026
3fcd58c
📝 Describe the SPI device slot and the chip models
GabrielCosme Sep 28, 2026
b710cc0
♻️ Make the simulator safe to add as a subproject
GabrielCosme Sep 28, 2026
5f670be
✨ Let the tools find a target's plugin outside the simulator
GabrielCosme Sep 28, 2026
48c415b
♻️ Give the program its thread and the target's types their own header
GabrielCosme Sep 28, 2026
ac8f255
🎨 Follow the shared style with clang 22
GabrielCosme Sep 28, 2026
3a079f9
✅ Move every test to doctest
GabrielCosme Sep 28, 2026
9a45388
🚨 Compile the simulator with the shared warnings
GabrielCosme Sep 28, 2026
68cedc3
🚨 Satisfy clang-tidy 22
GabrielCosme Sep 28, 2026
4ec7e7b
✨ Add a toy target that uses every feature of the engine
GabrielCosme Sep 28, 2026
2eb003c
🔨 Run every recipe as a CMake target over a script
GabrielCosme Sep 28, 2026
403e399
👷 Check the simulator on every push and pull request
GabrielCosme Sep 28, 2026
b14fb04
🐛 Name the toy's --turn-angle when its value is not a number
GabrielCosme Sep 28, 2026
a9fc65b
📝 List the headers a target may include in the README
GabrielCosme Sep 28, 2026
5638a40
📝 Name the robot tools by their CMake targets
GabrielCosme Sep 28, 2026
0ed3f06
✏️ Spell the simulator in American English
GabrielCosme Sep 28, 2026
f3ca02c
🔥 Drop the comments of the new source files
GabrielCosme Sep 28, 2026
1db3ca3
🔧 Declare MICRAS_SIM_EXACT once, at the simulator's root
GabrielCosme Sep 28, 2026
a9b69d1
💚 Give every test file its own name per process
GabrielCosme Sep 28, 2026
e4cde4f
🔥 Move the Micras target and the host HAL out of the simulator
GabrielCosme Sep 28, 2026
ac489d3
📝 Describe the simulator without the Micras target
GabrielCosme Sep 28, 2026
8b62287
✅ Scan every file outside targets/ for the names of a robot
GabrielCosme Sep 28, 2026
573f62b
✅ Let MICRAS_SKIP_VIEWER skip the viewer comparison wherever it runs
GabrielCosme Sep 28, 2026
492ca84
👷 Check out the simulator without submodules
GabrielCosme Sep 28, 2026
8846ab0
✏️ Name the tire material of the composed model the American way
GabrielCosme Sep 28, 2026
6761ab1
👷 Cache the fetch stamps with the simulator's fetched dependencies
GabrielCosme Sep 28, 2026
dec0c80
✅ Start the socket tests' servers on another port when theirs was taken
GabrielCosme Sep 28, 2026
9235774
♻️ Keep one baseline per robot and let git version it
GabrielCosme Oct 4, 2026
9dc04bb
✨ Apply the sliding friction of the skids as a force
GabrielCosme Oct 4, 2026
dc70c42
👷 Check each commit once, by its push, and pull requests only from forks
GabrielCosme Oct 4, 2026
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
10 changes: 8 additions & 2 deletions .clang-format
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
Language: Cpp
BasedOnStyle: LLVM
AccessModifierOffset: -4
AlignAfterOpenBracket: BlockIndent
AlignConsecutiveBitFields:
Expand All @@ -26,20 +27,25 @@ IncludeCategories:
SortPriority: 1
- Regex: '^".*"'
SortPriority: 2
IncludeIsMainRegex: '$'
# No include is treated as the main header, so that sorting preserves the existing
# grouping instead of promoting the header matching the source file name
IncludeIsMainRegex: 'NO_MAIN_INCLUDE'
IndentCaseLabels: true
IndentExternBlock: NoIndent
IndentPPDirectives: BeforeHash
IndentRequiresClause: false
IndentWidth: 4
IndentWrappedFunctionNames: true
InsertNewlineAtEOF: true
KeepEmptyLinesAtTheStartOfBlocks: false
LineEnding: LF
PackConstructorInitializers: NextLine
PointerAlignment: Left
SeparateDefinitionBlocks: Always
ShortNamespaceLines: 0
SortIncludes: Never
SortIncludes: CaseSensitive
SpaceInEmptyBlock: true
SpacesBeforeTrailingComments: 2
Standard: Latest
TabWidth: 4
...
36 changes: 33 additions & 3 deletions .clang-tidy
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
---
# llvm-include-order enforces LLVM's own ordering, which contradicts the project's
# .clang-format rules; clang-format is the single authority on include order here.
#
# The trailing group disables checks for constructs this project cannot contain. They match
# nothing, so they only cost time scanning the standard library and the Cube headers:
# string_view, coroutines, Objective-C, GoogleTest, the LLVM internal APIs, std::bind,
# iostreams, std::auto_ptr and std::random_shuffle (both removed in C++17), and printf.
# It also drops clang-analyzer-core.FixedAddressDereference, which every memory mapped
# peripheral access looks like by construction.
Checks:
-*,
bugprone-*,
Expand All @@ -14,8 +23,8 @@ Checks:
google-*,
llvm-*,
-llvm-header-guard,
-llvm-include-order,
misc-*,
-misc-include-cleaner,
-misc-use-anonymous-namespace,
modernize-*,
-modernize-use-nodiscard,
Expand All @@ -25,6 +34,19 @@ Checks:
-readability-duplicate-include,
-readability-magic-numbers,
-readability-math-missing-parentheses,
-bugprone-stringview-nullptr,
-cppcoreguidelines-no-suspend-with-lock,
-google-objc-*,
-google-upgrade-googletest-case,
-llvm-prefer-isa-or-dyn-cast-in-conditionals,
-llvm-prefer-register-over-unsigned,
-llvm-twine-local,
-modernize-avoid-bind,
-modernize-deprecated-ios-base-aliases,
-modernize-replace-auto-ptr,
-modernize-replace-random-shuffle,
-modernize-use-std-print,
-clang-analyzer-core.FixedAddressDereference,
HeaderFileExtensions:
- ''
- h
Expand All @@ -36,9 +58,17 @@ ImplementationFileExtensions:
- cc
- cpp
- cxx
HeaderFilterRegex: ''
FormatStyle: none
HeaderFilterRegex: '(include|config)/.*\.(hpp|tpp)$'
ExcludeHeaderFilterRegex: '(_deps|external)/'
FormatStyle: file
CheckOptions:
# The vendor HAL module headers are not standalone; they require stm32<family>xx_hal.h to have
# pulled in stm32<family>xx_hal_def.h first, so include-cleaner must not suggest or remove them.
# This is why micras_hal includes the generated main.h, which reaches the right one for the
# family it was generated for, instead of naming a module header of its own. main.h is on the
# list for the same reason: every symbol behind it resolves to a header already listed here, so
# nothing is credited to main.h and it would otherwise be reported as unused.
misc-include-cleaner.IgnoreHeaders: 'stm32.*;core_cm.*;cmsis.*;system_stm32.*;lsm6dsv.*;main\.h'
readability-identifier-length.MinimumVariableNameLength: 2
readability-identifier-length.IgnoredVariableNames: ^[nxyz]$
readability-identifier-length.MinimumParameterNameLength: 2
Expand Down
65 changes: 65 additions & 0 deletions .docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# syntax=docker/dockerfile:1.27

# >>> host stage >>>
###############################################################################
# Host tools: shared byte for byte by micras-lib, micras-simulation and #
# MicrasFirmware, whose CI compares the lines between the two markers #
###############################################################################
FROM ubuntu:26.04 AS host

# The compilers and the clang tooling are pinned to a major version, so that a distribution update
# can move neither the generated code nor the formatting rules and the enabled check set
ARG HOST_GCC_VERSION=15
ARG HOST_CLANG_VERSION=22

# The apt caches are kept in BuildKit cache mounts instead of the image layers, so the hook that
# deletes the downloaded packages after every install has to go
RUN rm -f /etc/apt/apt.conf.d/docker-clean

RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
--mount=type=cache,target=/var/lib/apt,sharing=locked \
apt-get update && \
apt-get install -y --no-install-recommends \
ca-certificates \
cmake \
doxygen \
git \
graphviz \
ninja-build \
python3 \
python3-matplotlib \
python3-numpy \
"gcc-${HOST_GCC_VERSION}" \
"g++-${HOST_GCC_VERSION}" \
"clang-${HOST_CLANG_VERSION}" \
"clang-format-${HOST_CLANG_VERSION}" \
"clang-tidy-${HOST_CLANG_VERSION}"

WORKDIR /project
# <<< host stage <<<

###############################################################################
# The simulator: what the viewer, the video and their checks need on top #
###############################################################################
FROM host AS simulator

ARG HOST_CLANG_VERSION=22

# GLFW and the OpenGL and EGL development files for the viewer and the video, Mesa's software renderer
# for a machine with no GPU, Xvfb for a window with no display, and ffmpeg, which encodes the video.
# clang's own sanitizer headers let clang-tidy read a sanitized build: MuJoCo's headers include them.
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
--mount=type=cache,target=/var/lib/apt,sharing=locked \
apt-get update && \
apt-get install -y --no-install-recommends \
"libclang-rt-${HOST_CLANG_VERSION}-dev" \
ffmpeg \
libegl-dev \
libegl-mesa0 \
libgl-dev \
libgl1-mesa-dri \
libglfw3-dev \
libglx-mesa0 \
libopengl-dev \
xauth \
xvfb
64 changes: 64 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
name: Build test lint and check the simulator

on:
push:
pull_request:
workflow_dispatch:

permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

# A push to a branch of this repository is checked once by its push run, so a pull request only runs
# here when it comes from a fork
jobs:
host:
name: 🧪 Build, tests, format, lint and checks
runs-on: ubuntu-latest
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.repository
timeout-minutes: 60
steps:
- name: 🔀 Checkout
uses: actions/checkout@v7

- name: 🐋 Build the simulator image
run: docker build --file .docker/Dockerfile --target simulator --tag micras-simulation:ci .docker

- name: 🗃️ Restore the fetched dependencies
uses: actions/cache@v6
with:
path: |
build/host-ci/_deps
build/host-ci/CMakeFiles/fc-stamp
key: deps-host-ci-${{ hashFiles('cmake/third_party.cmake', 'cmake/mujoco.cmake') }}

# One long lived container runs every step below, as the user that owns the checkout
- name: 📦 Start the simulator container
run: >
docker run --detach --name simulator --user "$(id -u):$(id -g)" --env HOME=/tmp
--volume "$PWD:/project" --workdir /project micras-simulation:ci sleep infinity

- name: ⚙️ Configure
run: docker exec simulator cmake --preset host-ci

- name: 🔨 Build
run: docker exec simulator cmake --build --preset host-ci

- name: 🧪 Run the tests
run: docker exec simulator ctest --preset host-ci

- name: 🎨 Check the formatting
run: docker exec simulator cmake --build --preset host-ci --target micras_sim_format_check

- name: 🚨 Lint
run: docker exec simulator cmake --build --preset host-ci --target micras_sim_lint

- name: ✅ Check the simulator
run: docker exec simulator cmake --build --preset host-ci --target micras_sim_check

- name: 🧹 Stop the simulator container
if: always()
run: docker rm --force simulator
2 changes: 0 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,4 @@ runs/
build/
.cache/
__pycache__/
.omc/
compile_commands.json
third_party/_deps/
4 changes: 0 additions & 4 deletions .gitmodules

This file was deleted.

Loading
Loading