- π Summary
- π Folder structure
- π¦οΈ Packages
- π Operating the robot
- π¨ Building
- π Running
- π§ͺ Testing
- π Debugging
- π Code style
- π Docker
- π Documentation
- π οΈ Windows Development Environment
- π₯ Contributing
- β¨ Contributors
- .docker/ - Docker build files for CI/CD.
- .github/ - GitHub Actions workflow files.
- .vscode/ - Visual Studio Code configuration files.
- cmake/ - Functions to include in the main CMake.
- config/ - Target and constants configuration values.
- cube/ - STM32CubeMX configuration and build files.
- docs/ - Generated documentation output, not tracked by Git.
- include/ - Header files for class definitions.
- micras_*/ - Project packages, see Packages.
- src/ - Source file for class implementations and executables.
- tests/ - Executable test files.
- micras_core - Hardware independent building blocks, such as controllers, filters and the state machine.
- micras_hal - Wrapper to the STM32 HAL, implementing the needed functionalities in C++ classes.
- micras_proxy - Intermediate abstraction layer for the hardware components.
- micras_nav - Mapping, planning and control algorithms to navigate inside a maze.
- micras_comm - The link over the radio: framing, the session and the variables it carries.
Each one is a library in its own right, and they depend downwards only: micras_proxy on
micras_hal and that on micras_core, while micras_nav depends on micras_core alone. The
navigation takes plain measurements in and gives a plain motor command out, so it cannot reach the
hardware and builds on anything with a C++23 compiler, which is how it is simulated and tested on a
computer. The application in src/ is the only place where the proxies and the navigation meet.
None of the packages names a file or a symbol that STM32CubeMX generates for a particular project,
so the generated tree is reached only from config/targets/, where the handles and the
initialization functions of a board are written down and handed to the packages through their
configuration structs. The same directory holds robot.hpp, the physical description of the robot
that every speed, turn, gain and sensing window of the navigation is computed from.
The one name micras_hal uses from outside itself is stm32cubemx, the interface target the
STM32CubeMX CMake generator writes for every project, carrying the CMSIS and vendor HAL include
directories and the device macros. Any generated project already has it, so another project reuses
the packages by adding their sources and linking the layer it wants:
add_subdirectory(micras_core)
add_subdirectory(micras_hal)
add_subdirectory(micras_proxy)
add_subdirectory(micras_nav)
target_link_libraries(your_target PRIVATE micras::nav micras::proxy)Everything else travels through the targets: the include directories, the C++ standard the sources
need, and the vendor HAL headers. FetchContent_MakeAvailable works the same way, and is the
sensible option for a cross compiled target, where a prebuilt archive is only usable by a project
whose architecture flags match exactly.
The button starts everything, and the four switches choose how.
| Button press | What happens |
|---|---|
| Short | Search run: the robot explores until it reaches the goal, saves the maze, and then keeps exploring on the way back until the maze proves that the fastest route is known. It parks where a run starts from and saves the maze again. |
| Long | Fast run: the maze is loaded, the fastest route for the current switches is planned, and the robot runs it. |
| Extra long | Maintenance procedure, chosen by the switches as listed below. |
| Switch | Fast run | Extra long press, with the other two of these three off |
|---|---|---|
| Fan | The fan runs, and its downforce is counted on. | The fan runs during the procedure, but is not part of the choice. |
| Racing line | The robot drives the smoothest line through the cells of the fastest route instead of the route itself, if one is found. | Drive identification: the robot drives forward and back within 0.8 m ahead of where it starts, then turns to each side, and fits the constants of its drive train. It needs that stretch of free floor, plus some margin on both ends in case the model it starts from is off. |
| Boost | A larger share of the available traction is used. | Gyroscope scale calibration: facing a wall, the robot turns five times in place and compares what the gyroscope integrated with what the wall says. |
| Risky | The turns designed with the smaller safety margin are used. With the racing line, the line goes through the route planned without those turns, since a line keeps the margin of the careful turns, and it is driven if it is faster than the route of the risky turns. |
With none of those three on, an extra long press calibrates the wall sensors in two steps: first the side sensors, and after a pause the front sensors, with the robot centered in a cell facing a wall. The side sensors point 45 degrees ahead and never see the walls of their own cell: with the robot centered in a cell, they reach the side walls of the next one. So the first step is taken centered in a corridor at least two cells long, with no wall ahead and walls on both sides of the next cell too. Anywhere else they read the wall ahead, at less than half the distance, and the calibration comes out about five times off.
The results of the maintenance procedures are not stored. They are variables of the pool
(identification/*, gyroscope/*, wall_reference/* and wall_spread/*), to be read over the link
and typed into config/targets/<board>/robot.hpp and target.hpp.
To build the project, it is first necessary to install some dependencies:
sudo apt install cmake make gcc-arm-none-eabi libnewlib-arm-none-eabi libstdc++-arm-none-eabi-newlibThe STM32CubeMX program is also required. After the installation is completed, it is necessary to set the CUBE_CMD environment variable to the path of the STM32CubeMX executable or add it to the PATH.
Start the build process by creating a build folder inside the project root:
mkdir build && cd buildAnd then generating the build commands:
cmake ..The board revision to build for is selected with the BOARD_VERSION variable, which must match
one of the cube/micras_<version>.ioc files. It defaults to v1:
cmake .. -DBOARD_VERSION=v0The project can then be compiled by running:
make -jYou can list all available make commands by running:
make helpmeThe binaries can be flashed into the microcontroller using the STM32CubeProgrammer, which needs to be installed and added to the PATH variable. For flashing the main program, run the following command:
make flash -jIf the project has not been compiled yet, this command will also automatically compile the target.
Any test can be compiled and run using the same commands as the ones used for the main executable, but adding the test name without the file extension at the end:
make [test_name] -jmake flash_[test_name] -jIt is also possible to build all tests at once, using the command:
make test_all -jThe parts with no hardware behind them, the variable pool, the flash image, the framing and the session layer, also have tests that build with the host compiler and run in the terminal:
cmake -S tests/host -B build/host && cmake --build build/host && ctest --test-dir build/hostIt is possible to debug the project using GDB. To do that, first install gdb-multiarch, on Ubuntu, just run:
sudo apt install gdb-multiarchTo debug the project, you need to run the cmake command with BUILD_TYPE set to Debug or RelWithDebInfo, for example:
cmake .. -DBUILD_TYPE=DebugIf you are using Visual Studio Code, install the Cortex Debug extension. Then, generate the launch files for debugging with the command:
make debugIt is also possible to debug test executables, by first running the command:
make debug_[test_name]There are three configurations for debugging present at the .vscode/launch.json file that uses different programs:
For each debug type, you need to install the respective GDB server.
If using J-Link, flash the firmware by running the following command:
make jflash -jor if you want to flash a test:
make jflash_[test_name] -jThe project uses clang-format to format files, there is a .clang-format with the formatting rules for the project. To install it, on Ubuntu, run the following command on the terminal:
sudo apt install clang-formatIn order to format the project, run the following command in the build folder:
make formatTo only check if the files are formatted, without changing them, run make format_check.
The project uses a linter in order to follow the best code practices. The linter used is clang-tidy, there is a .clang-tidy with the linting rules for the project. To install it on Ubuntu, run the following command on the terminal:
sudo apt install clang-tidyThe linting process is done by running the following command in the build folder:
make lintIt is also possible to lint the project and let the linter fix it using its suggestions:
make lint_fixDocker can be used to build the project inside a container, which makes it possible to implement CI/CD pipelines and develop in any environment, for this, it is necessary to have Docker installed on your system.
The project can be built without entering a container by running the following command:
docker compose run buildThis also works for formatting (docker compose run check-format) and linting (docker compose run lint).
To enter a container and mount the project folder, run the following command:
docker compose run devFrom inside the container, most of the previous sections can be executed, such as building and code style.
If Visual Studio Code is being used, it is possible to use the Dev Containers extension to develop inside the container with the other recommended extensions.
The project is documented using Doxygen. In Ubuntu, it is possible to install it with the following command:
sudo apt install doxygen graphviz texlive-latex-recommended texlive-latex-extra texlive-fonts-recommendedFor other operating systems, you can see download options on the official Doxygen page.
The HTML documentation is published to GitHub Pages on every push to main. To generate it
locally, run the following command inside the build folder. The output is written to the
docs/ folder, which is not tracked by Git:
make docsThat also writes the LaTeX sources. To turn them into docs/refman.pdf, which additionally
requires a LaTeX distribution, run:
make docs_pdfThe configuration is in the file Doxyfile, and the HTML theme is doxygen-awesome-css, fetched by CMake.
If you are developing on a Windows machine using Windows Subsystem for Linux (WSL), we recommend installing the following tools on Windows and add them to the WSL PATH:
Our recommended workflow for Windows users is to use WSL for building the project while running STM32CubeMX, flashing tools, and GDB servers directly in the Windows environment. This setup provides a smoother development experience and avoids the need to passthrough the USB connections to WSL, allowing you to use the native Windows tools for flashing and debugging the project inside WSL.
However, if you prefer to keep everything inside WSL, you can manually define the environment variables JLINK_CMD and PROGRAMMER_CMD to point to the respective executables. If you need to passthrough USB devices to WSL, refer to the official WSL USB documentation for setup instructions.
Note
To debug while using WSL, it is recommended to enable Mirrored mode networking, so that you can directly access the ports created by the GDB server from inside the WSL.
To learn how to contribute to the project, see the following contribution guidelines.
-
Use the present tense ("Add feature" not "Added feature").
-
Use the imperative mood ("Move cursor to..." not "Moves cursor to...").
-
It is strongly recommended to start a commit message with a related emoji:
- π
:memo:for documentation. - π
:bug:for bug issues. - π
:ambulance:for critical fixes. - π¨
:art:for formatting code. - β¨
:sparkles:for new features.
For more examples, see this reference.
- π
The project workflow is based on GitHub Flow.
Thanks goes to these wonderful people (emoji key):
Gabriel Cosme Barbosa π» π π¬ π |
Pedro de Santi π» π π¬ π |
Matheus Rezende Pereira π» π π¬ π |
Eduardo Barreto π» π π¬ π |
Claudio Dardengo π» π π¬ π |
This project follows the all-contributors specification. Contributions of any kind welcome!