Skip to content

About

NTF Classic Micromouse project

Topics

Resources

Stars

15 stars

Watchers

2 watching

Forks

Repository files navigation

micras_firmware_logo

NTF Classic Micromouse project with an STM32 microcontroller

Made with C++ Uses STM32CubeMX Built for Embedded Devices

πŸ“‘ Summary

πŸ“ Folder structure

  • .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.

πŸ“¦οΈ Packages

  • 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.

🐭 Operating the robot

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.

πŸ”¨ Building

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-newlib

The 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 build

And 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=v0

The project can then be compiled by running:

make -j

You can list all available make commands by running:

make helpme

πŸš€ Running

The 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 -j

If the project has not been compiled yet, this command will also automatically compile the target.

πŸ§ͺ Testing

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] -j
make flash_[test_name] -j

It is also possible to build all tests at once, using the command:

make test_all -j

The 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/host

πŸ› Debugging

It is possible to debug the project using GDB. To do that, first install gdb-multiarch, on Ubuntu, just run:

sudo apt install gdb-multiarch

To debug the project, you need to run the cmake command with BUILD_TYPE set to Debug or RelWithDebInfo, for example:

cmake .. -DBUILD_TYPE=Debug

If you are using Visual Studio Code, install the Cortex Debug extension. Then, generate the launch files for debugging with the command:

make debug

It 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 -j

or if you want to flash a test:

make jflash_[test_name] -j

πŸ’„ Code style

🎨 Format

The 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-format

In order to format the project, run the following command in the build folder:

make format

To only check if the files are formatted, without changing them, run make format_check.

🚨 Linter

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-tidy

The linting process is done by running the following command in the build folder:

make lint

It is also possible to lint the project and let the linter fix it using its suggestions:

make lint_fix

πŸ‹ Docker

Docker 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.

🐳 Building

The project can be built without entering a container by running the following command:

docker compose run build

This also works for formatting (docker compose run check-format) and linting (docker compose run lint).

πŸ§‘β€πŸ’» Development

To enter a container and mount the project folder, run the following command:

docker compose run dev

From 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.

πŸ“ Documentation

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-recommended

For 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 docs

That also writes the LaTeX sources. To turn them into docs/refman.pdf, which additionally requires a LaTeX distribution, run:

make docs_pdf

The configuration is in the file Doxyfile, and the HTML theme is doxygen-awesome-css, fetched by CMake.

πŸ› οΈ Windows Development Environment

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.

πŸ‘₯ Contributing

To learn how to contribute to the project, see the following contribution guidelines.

πŸ’¬ Git commit messages

  • 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.

πŸ”€ Git workflow

The project workflow is based on GitHub Flow.

✨ Contributors

Thanks goes to these wonderful people (emoji key):

Gabriel Cosme Barbosa
Gabriel Cosme Barbosa

πŸ’» πŸ“– πŸ”¬ πŸ‘€
Pedro de Santi
Pedro de Santi

πŸ’» πŸ“– πŸ”¬ πŸ‘€
Matheus Rezende Pereira
Matheus Rezende Pereira

πŸ’» πŸ“– πŸ”¬ πŸ‘€
Eduardo Barreto
Eduardo Barreto

πŸ’» πŸ“– πŸ”¬ πŸ‘€
Claudio Dardengo
Claudio Dardengo

πŸ’» πŸ“– πŸ”¬ πŸ‘€

This project follows the all-contributors specification. Contributions of any kind welcome!

About

NTF Classic Micromouse project

Topics

Resources

Stars

15 stars

Watchers

2 watching

Forks

Releases

Packages

Contributors

Languages